structured

This commit is contained in:
Sanjib Sen 2025-01-16 14:38:12 +06:00
parent 9f706092a7
commit 443b19c7c0
7 changed files with 143 additions and 47 deletions

72
src/api/index.ts Normal file
View file

@ -0,0 +1,72 @@
import { Elysia, t } from "elysia";
import { betterAuthView } from "../lib/auth/auth-view";
import { getAuthConfig, getBaseConfig } from "../lib/utils/env";
import { router } from "./routes";
const baseConfig = getBaseConfig();
const authConfig = getAuthConfig();
export const api = new Elysia({
name: baseConfig.SERVICE_NAME,
prefix: "/api",
detail: {
summary: `Get status`,
description: `Get status for ${baseConfig.SERVICE_NAME}`,
externalDocs: {
description: "Auth API",
url: `${authConfig.BETTER_AUTH_URL}/docs`,
},
},
})
.all("/auth/*", betterAuthView)
.use(router)
.get(
"",
() => {
return {
message: `Server is running`,
success: true,
name: baseConfig.SERVICE_NAME,
status: "active",
docs: {
default: "/api/docs",
auth: "/api/auth/docs",
},
};
},
{
response: {
200: t.Object(
{
message: t.String({ default: `Server is running` }),
success: t.Boolean({ default: true }),
name: t.String({ default: baseConfig.SERVICE_NAME }),
status: t.String({ default: `active` }),
docs: t.Object({
default: t.String({ default: "/api/docs" }),
auth: t.String({ default: "/api/auth/docs" }),
}),
},
{
description: "Success",
}
),
404: t.Object(
{
message: t.String({ default: `Not found` }),
success: t.Boolean({ default: false }),
name: t.String({ default: baseConfig.SERVICE_NAME }),
status: t.String({ default: `active` }),
docs: t.Object({
default: t.String({ default: "/api/docs" }),
auth: t.String({ default: "/api/auth/docs" }),
}),
},
{
description: "Not found",
}
),
},
}
);

6
src/api/routes/index.ts Normal file
View file

@ -0,0 +1,6 @@
import { Elysia, t } from "elysia";
import { noteRouter } from "./note/note.route";
export const router = new Elysia().use(noteRouter)

View file

@ -1,6 +1,6 @@
import { and, eq, notExists } from "drizzle-orm"; import { and, eq, notExists } from "drizzle-orm";
import { db } from "../../db"; import { db } from "../../../db";
import { note } from "../../db/schema/note"; import { note } from "../../../db/schema/note";
import { CreateNote } from "./note.model"; import { CreateNote } from "./note.model";
export class NoteController { export class NoteController {

View file

@ -1,6 +1,6 @@
import { createSelectSchema } from "drizzle-typebox"; import { createSelectSchema } from "drizzle-typebox";
import { t } from "elysia"; import { t } from "elysia";
import { note } from "../../db/schema/note"; import { note } from "../../../db/schema/note";
import { InferInsertModel, InferSelectModel } from "drizzle-orm"; import { InferInsertModel, InferSelectModel } from "drizzle-orm";

View file

@ -1,8 +1,8 @@
import { Elysia, error, t } from "elysia"; import { Elysia, error, t } from "elysia";
import { createNoteSchema, NoteSchema, successDeleteNoteResponse, successGetNoteResponse } from "./note.model"; import { createNoteSchema, NoteSchema, successDeleteNoteResponse, successGetNoteResponse } from "./note.model";
import { NoteController } from "./note.controller"; import { NoteController } from "./note.controller";
import { userMiddleware } from "../../middlewares/auth-middleware"; import { userMiddleware } from "../../../middlewares/auth-middleware";
import { commonResponses } from "../../lib/utils/common"; import { commonResponses } from "../../../lib/utils/common";
export const noteRouter = new Elysia({ export const noteRouter = new Elysia({
prefix: "/note", prefix: "/note",
@ -18,6 +18,15 @@ export const noteRouter = new Elysia({
note: NoteSchema, note: NoteSchema,
}) })
.derive(({ request }) => userMiddleware(request)) .derive(({ request }) => userMiddleware(request))
.onError(({ error, code, }) => {
console.error(error);
return {
message: "",
success: false,
data: null,
error: code.toString()
};
})
.get( .get(
"", "",
async ({ note, user, query}) => { async ({ note, user, query}) => {

View file

@ -2,30 +2,47 @@ import { Elysia } from "elysia";
import { swagger } from "@elysiajs/swagger"; import { swagger } from "@elysiajs/swagger";
import { opentelemetry } from "@elysiajs/opentelemetry"; import { opentelemetry } from "@elysiajs/opentelemetry";
import { serverTiming } from "@elysiajs/server-timing"; import { serverTiming } from "@elysiajs/server-timing";
import { cors } from '@elysiajs/cors' import { cors } from "@elysiajs/cors";
import { noteRouter } from "./api/note/note.route";
import { betterAuthView } from "./lib/auth/auth-view";
import { getBaseConfig, validateEnv } from "./lib/utils/env"; import { getBaseConfig, validateEnv } from "./lib/utils/env";
import { api } from "./api";
const baseConfig = getBaseConfig() const baseConfig = getBaseConfig();
const app = new Elysia()
.use(cors())
.use(opentelemetry({
"serviceName": baseConfig.SERVICE_NAME
}))
.use(swagger({
path: "/docs",
}))
.use(serverTiming())
.onError(({ error, code }) => {
if (code === "NOT_FOUND") return "Not Found :(";
console.error(error);
})
.all("/api/auth/*", betterAuthView)
.use(noteRouter)
.get("/", () => `${baseConfig.SERVICE_NAME} Server is Running`)
validateEnv(); validateEnv();
const app = new Elysia()
.use(cors())
.use(
opentelemetry({
serviceName: baseConfig.SERVICE_NAME,
})
)
.use(serverTiming())
.use(
swagger({
path: "/api/docs",
documentation: {
info: {
title: baseConfig.SERVICE_NAME,
version: "0.0.1",
description: `API docs for ${baseConfig.SERVICE_NAME}`,
},
},
})
)
.onError(({ error, code }) => {
if (code === "NOT_FOUND")
return {
message: `Not Found`,
success: false,
name: baseConfig.SERVICE_NAME,
status: "active",
docs: {
default: "/api/docs",
auth: "/api/auth/docs",
},
};
console.error(error);
})
.use(api);
app.listen(baseConfig.PORT); app.listen(baseConfig.PORT);
console.log(`Server is running on: http://127.0.0.1:${baseConfig.PORT}`) console.log(`Server is running on: http://127.0.0.1:${baseConfig.PORT}`);

View file

@ -5,10 +5,8 @@ export const commonResponses = {
{ {
data: t.Null(), data: t.Null(),
success: t.Boolean({ default: false }), success: t.Boolean({ default: false }),
message: t.String({ default: "Bad Request" }), message: t.String({ default: "" }),
error: t.String({ error: t.Number({ default: 400 }),
default: "Missing parameters, or invalid parameters.",
}),
}, },
{ {
description: description:
@ -19,10 +17,8 @@ export const commonResponses = {
{ {
data: t.Null(), data: t.Null(),
success: t.Boolean({ default: false }), success: t.Boolean({ default: false }),
message: t.String({ default: "Unauthorized" }), message: t.String({ default: "" }),
error: t.String({ error: t.Number({ default: 401 }),
default: "User needs to sign in to access this resource",
}),
}, },
{ {
description: "Unauthorized. Due to missing or invalid authentication.", description: "Unauthorized. Due to missing or invalid authentication.",
@ -32,10 +28,8 @@ export const commonResponses = {
{ {
data: t.Null(), data: t.Null(),
success: t.Boolean({ default: false }), success: t.Boolean({ default: false }),
message: t.String({ default: "Forbidden" }), message: t.String({ default: "" }),
error: t.String({ error: t.Number({ default: 403 }),
default: "User does not have permission to access this resource",
}),
}, },
{ {
description: description:
@ -46,8 +40,8 @@ export const commonResponses = {
{ {
data: t.Null(), data: t.Null(),
success: t.Boolean({ default: false }), success: t.Boolean({ default: false }),
message: t.String({ default: "Not Found" }), message: t.String({ default: "" }),
error: t.String({ default: "Requested resource has not found" }), error: t.Number({ default: 404 }),
}, },
{ {
description: "Not Found. The requested resource was not found.", description: "Not Found. The requested resource was not found.",
@ -57,10 +51,8 @@ export const commonResponses = {
{ {
data: t.Null(), data: t.Null(),
success: t.Boolean({ default: false }), success: t.Boolean({ default: false }),
message: t.String({ default: "Too Many Requests" }), message: t.String({ default: "" }),
error: t.String({ error: t.Number({ default: 429 }),
default: "RUser has exceeded the rate limit. Try again later.",
}),
}, },
{ {
description: description:
@ -71,8 +63,8 @@ export const commonResponses = {
{ {
data: t.Null(), data: t.Null(),
success: t.Boolean({ default: false }), success: t.Boolean({ default: false }),
message: t.String({ default: "Internal Server Error" }), message: t.String({ default: "" }),
error: t.String({ default: "Server faced an error" }), error: t.Number({ default: 500 }),
}, },
{ {
description: description: