This repository has been archived by the owner on Jun 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(api): 🚀 Add anime data handling and environment setup
- Introduced `.env.example` for environment variable management. - Moved and updated `package.json` within the `apps/api` directory, adding new dependencies and scripts for development and build processes. - Created a new Prisma migration for the `Anime` table, outlining the structure for anime data storage. - Developed new services and routes for fetching, caching, and serving anime data. - Configured Docker Compose with PostgreSQL and Redis services to support local development. - Enhanced the codebase with TypeScript configurations and utility functions for environment variable and fetch operations.
- Loading branch information
Showing
23 changed files
with
242 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Rename this file to ".env" and put your datas | ||
PROXY_URL= | ||
NEKO_JSON_URL= | ||
NEKO_URL= | ||
HOST= | ||
PORT= | ||
JWT_SECRET= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,13 @@ | ||
{ | ||
"name": "@gazes/api", | ||
"scripts": { | ||
"dev": "bun run src/index.ts", | ||
"dev": "bun run --hot src/index.ts", | ||
"build": "bun build src/index.ts --outdir dist/ --target bun" | ||
}, | ||
"dependencies": { | ||
"@fastify/type-provider-typebox": "^4.0.0", | ||
"@gazes/types": "workspace:*", | ||
"fastify": "^4.26.2", | ||
"@gazes/types": "workspace:*" | ||
"redis": "^4.6.13" | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
apps/api/prisma/migrations/20240403165832_init/migration.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
-- CreateTable | ||
CREATE TABLE "Anime" ( | ||
"id" INTEGER NOT NULL, | ||
"titleOriginal" TEXT NOT NULL, | ||
"titleEnglish" TEXT, | ||
"titleRomanized" TEXT, | ||
"titleFrench" TEXT, | ||
"alternativeTitles" TEXT, | ||
"mediaType" TEXT NOT NULL, | ||
"airingStatus" TEXT NOT NULL, | ||
"externalUrl" TEXT NOT NULL, | ||
"genres" TEXT[], | ||
"coverImageUrl" TEXT NOT NULL, | ||
"popularityScore" DOUBLE PRECISION NOT NULL, | ||
"averageScore" DOUBLE PRECISION NOT NULL, | ||
"startYear" INTEGER NOT NULL, | ||
"episodesCount" INTEGER, | ||
"synopsis" TEXT, | ||
"bannerImageUrl" TEXT, | ||
|
||
CONSTRAINT "Anime_pkey" PRIMARY KEY ("id") | ||
); | ||
|
||
-- CreateIndex | ||
CREATE UNIQUE INDEX "Anime_id_key" ON "Anime"("id"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Please do not edit this file manually | ||
# It should be added in your version-control system (i.e. Git) | ||
provider = "postgresql" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,30 @@ | ||
import type { TypeBoxTypeProvider } from "@fastify/type-provider-typebox"; | ||
import { Glob } from "bun"; | ||
import fastify from "fastify"; | ||
import { join } from "node:path"; | ||
import { createClient, type RedisClientType } from "redis"; | ||
import { AnimeService } from "./services/animeService"; | ||
import { PrismaClient } from "prisma/prisma-client"; | ||
|
||
// Initialize a Fastify application instance with specific configurations. | ||
export const app = fastify({ | ||
logger: true, // Enable loggin for the application | ||
disableRequestLogging: true, // Disable request logging to avoid clutter in the log output | ||
}); | ||
}).withTypeProvider<TypeBoxTypeProvider>(); | ||
|
||
// Synamically import and register router modules found by globbing thep roject directory for files | ||
// with a ".router." in their names. | ||
for await (const file of new Glob("**/*Router.*").scan(import.meta.dir)) { | ||
const prismaClient = new PrismaClient(); | ||
const redisClient = (await createClient().connect()) as RedisClientType; | ||
|
||
const animeService = new AnimeService(redisClient, prismaClient) | ||
await animeService.updateDatabase() | ||
|
||
// Register each found router module with the Fastify application. | ||
// The router modules are expected to export a default function that defines routes. | ||
app.register((await import(join(import.meta.dir, file))).default); | ||
app.register((await import(join(import.meta.dir, file))).default, { | ||
prismaClient, | ||
redisClient, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { app } from "@/app"; | ||
|
||
const { ADDRESS = "0.0.0.0", PORT = "3000" } = Bun.env; | ||
|
||
app.listen({ port: Number.parseInt(PORT, 10), host: ADDRESS }, (error) => { | ||
if (error) { | ||
console.error(error); | ||
process.exit(1); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { AnimeService } from "@/services/animeService"; | ||
import { AnimeListQuerystring, type RouteOptions } from "@/types/routeTypes"; | ||
import type { FastifyInstance } from "fastify"; | ||
|
||
export default async function ( | ||
app: FastifyInstance, | ||
{ prismaClient, redisClient }: RouteOptions, | ||
) { | ||
const animeService = new AnimeService(redisClient, prismaClient); | ||
|
||
app.get<{ Querystring: AnimeListQuerystring }>( | ||
"/", | ||
{ | ||
schema: { querystring: AnimeListQuerystring }, | ||
}, | ||
(request, response) => { | ||
const { page = 1, title, genres, status, releaseDate } = request.query; | ||
|
||
}, | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import type { RedisClientType } from "redis"; | ||
import { CacheService } from "./cacheService"; | ||
import { fetchType } from "@/utils/fetchUtils"; | ||
import { getEnv } from "@/utils/envUtils"; | ||
import type { Anime, PrismaClient } from "@prisma/client"; | ||
|
||
const HOUR = 3.6e+6; | ||
|
||
export class AnimeService { | ||
private cacheService: CacheService; | ||
|
||
constructor( | ||
private redisClient: RedisClientType, | ||
private prismaClient: PrismaClient, | ||
) { | ||
this.cacheService = new CacheService(redisClient); | ||
} | ||
|
||
public async updateDatabase() { | ||
await this.prismaClient.anime.deleteMany({}) | ||
const animesList: any[] = await fetchType(getEnv("NEKO_JSON_URL"), "json") | ||
|
||
const animesData: Anime[] = animesList.map(anime => ({ | ||
id: anime.id, | ||
titleOriginal: anime.title, | ||
titleEnglish: anime.title_english, | ||
titleRomanized: anime.title_romanji, | ||
titleFrench: anime.title_french, | ||
alternativeTitles: anime.others, | ||
mediaType: anime.type, | ||
airingStatus: anime.type === "1" ? "en cours" : "finis", | ||
popularityScore: anime.popularity, | ||
externalUrl: anime.url, | ||
genres: anime.genres, | ||
coverImageUrl: anime.url_image, | ||
averageScore: Number.parseFloat(anime.score), | ||
startYear: Number.parseInt(anime.start_date_year), | ||
episodesCount: Number.parseInt(anime.nb_eps), | ||
bannerImageUrl: null, | ||
synopsis: null | ||
})) | ||
|
||
await this.prismaClient.anime.createMany({ | ||
data: animesData, | ||
skipDuplicates: true | ||
}) | ||
|
||
setInterval(this.updateDatabase, HOUR) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import type { RedisClientType } from "redis"; | ||
|
||
export class CacheService { | ||
constructor( | ||
private readonly redisClient: RedisClientType | ||
) {} | ||
|
||
async setCache(key: string, value: unknown, ttl = 3600): Promise<void> { | ||
const stringValue = JSON.stringify(value); | ||
await this.redisClient.setEx(key, ttl, stringValue); | ||
} | ||
|
||
async getCache<T>(key: string): Promise<T | undefined> { | ||
const cachedValue = await this.redisClient.get(key); | ||
if (!cachedValue) return undefined; | ||
|
||
return JSON.parse(cachedValue) as T; | ||
} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import type { PrismaClient } from "@prisma/client"; | ||
import { Type, type Static } from "@sinclair/typebox"; | ||
import type { RedisClientType } from "redis"; | ||
|
||
// Route-related types and interfaces below | ||
|
||
export type RouteOptions = { | ||
prismaClient: PrismaClient; | ||
redisClient: RedisClientType; | ||
}; | ||
|
||
export type SuccessResponse = { | ||
data: unknown; | ||
error: never; | ||
}; | ||
|
||
export type ErrorResponse = { | ||
data: never; | ||
error: { | ||
title: string; | ||
detail: string; | ||
}; | ||
}; | ||
|
||
export type Response = SuccessResponse|ErrorResponse | ||
|
||
export const AnimeListQuerystring = Type.Object({ | ||
page: Type.Optional(Type.Number()), | ||
title: Type.Optional(Type.String()), | ||
genres: Type.Optional(Type.String()), | ||
status: Type.Optional(Type.Number()), | ||
releaseDate: Type.Optional(Type.Number()), | ||
}); | ||
|
||
export type AnimeListQuerystring = Static<typeof AnimeListQuerystring> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export function getEnv(key: string): string { | ||
const value = Bun.env[key] | ||
if (!value) throw `Missing ${key} env variable` | ||
return value | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export async function fetchType<T>( | ||
url: string, | ||
type: "json" | "text", | ||
): Promise<T> { | ||
const response = await fetch(url); | ||
if (!response.ok) throw Error("Error fetching the URL"); | ||
return await response[type](); | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"$schema": "https://biomejs.dev/schemas/1.6.3/schema.json", | ||
"organizeImports": { | ||
"enabled": true | ||
}, | ||
"linter": { | ||
"enabled": true, | ||
"rules": { | ||
"recommended": true, | ||
"suspicious": { | ||
"noExplicitAny":"off" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
services: | ||
|
||
db: | ||
image: postgres:alpine | ||
restart: always | ||
shm_size: 128mb | ||
environment: | ||
POSTGRES_USER: dev | ||
POSTGRES_PASSWORD: dev | ||
POSTGRES_DB: pg-dev | ||
ports: | ||
- "5432:5432" | ||
|
||
redis: | ||
image: 'redislabs/redismod' | ||
ports: | ||
- '6379:6379' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
b436bfd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GNU-ify your project dude
b436bfd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://tenor.com/view/richard-stallman-stallman-rms-emacs-gnu-gif-23943451