ডকুমেন্টেশনJavaScript ব্যাকএন্ড
ফাস্টফাই থেকে নেক্সি পর্যন্ত
নেক্সিতে একটি ফাস্টফাই রুট src/routes/ এর অধীনে একটি Python ফাইল হয়ে যায়: JSON স্কিমাগুলি Pydantic মডেলে পরিণত হয়, একটি prefix সহ প্লাগইনগুলি ফোল্ডারে পরিণত হয় এবং হুকগুলি dependencies.py এবং middleware.py ফাইলে পরিণত হয়।
নীচের প্রতিটি বিভাগ একটি Fastify অভ্যাস দেখায়, তারপর Nexy তে একই জিনিস।
একটি রুট
import Fastify from "fastify"; const app = Fastify({ logger: true }); app.get("/api/hello", async () => ({ message: "Hello" })); await app.listen({ port: 3000 });ফাইল পাথ হল URL, এবং ফাংশনের নাম হল পদ্ধতি:
async def GET(): return {"message": "Hello"}প্রতিটি অনুরোধ তার পদ্ধতি, পথ, স্থিতি এবং সময় দিয়ে লগ করা হয়, সেট আপ করার জন্য কোন লগার ছাড়াই।
প্যারাম এবং কোয়েরিস্ট্রিং স্কিমা
app.get( "/api/users/:id", { schema: { params: { type: "object", properties: { id: { type: "integer" } } }, querystring: { type: "object", properties: { fields: { type: "string" } } }, }, }, async (request) => ({ id: request.params.id, fields: request.query.fields }),);স্কিমা হল স্বাক্ষর: [id] ফাইলের নামে, পরামিতিগুলিতে প্রকারগুলি:
async def GET(id: int, fields: str | None = None): return {"id": id, "fields": fields}বডি স্কিমা
app.post( "/api/items", { schema: { body: { type: "object", required: ["name", "price"], properties: { name: { type: "string" }, price: { type: "number", exclusiveMinimum: 0 } }, }, }, }, async (request, reply) => reply.code(201).send(request.body),);from pydantic import BaseModel, Field from nexy.http import JSONResponse class NewItem(BaseModel): name: str price: float = Field(gt=0) async def POST(item: NewItem): return JSONResponse(item.model_dump(), status_code=201)একটি শরীর যা উত্তর দেয় 422, যেখানে ফাস্টফাই উত্তর দেয় 400।
প্রতিক্রিয়া স্কিম
app.get( "/api/me", { schema: { response: { 200: { type: "object", properties: { name: { type: "string" } } }, }, }, }, async () => ({ name: "Ada", passwordHash: "x" }),);রিটার্ন টাইপ রেসপন্স স্কিমা যা করে তা করে: যে ক্ষেত্রগুলি এটি ঘোষণা করে না তা বাদ দেওয়া হয়।
from pydantic import BaseModel class PublicUser(BaseModel): name: str async def GET() -> PublicUser: return {"name": "Ada", "password_hash": "x"}একটি উপসর্গ সহ প্লাগইন
export default async function admin(app) { app.get("/stats", async () => ({ users: 3 }));}app.register(admin, { prefix: "/admin" });ফোল্ডারটি উপসর্গ, এবং কিছুই নিবন্ধিত নেই:
async def GET(): return {"users": 3}preHandler এবং onRequest হুক
export default async function admin(app) { app.addHook("preHandler", async (request, reply) => { if (request.headers["x-role"] !== "admin") { return reply.code(403).send({ error: "Admins only" }); } });}একটি প্লাগইন স্কোপ করা একটি হুক হল তার ফোল্ডারে একটি dependencies.py:
from nexy.http import Header, HTTPException def require_admin(x_role: str = Header("")) -> None: if x_role != "admin": raise HTTPException(status_code=403, detail="Admins only") dependencies = [require_admin]onSend এবং onResponse হুক
app.addHook("onSend", async (request, reply, payload) => { reply.header("x-app", "demo"); return payload;});কোড পরে call_next আউট হওয়ার পথে একটি middleware.py রানে:
from nexy.http import Request async def middleware(request: Request, call_next): response = await call_next(request) response.headers["x-app"] = "demo" return responsedecorate এবং decorateRequest
app.decorate("db", { users: () => [{ name: "Ada" }] }); app.get("/api/users", async function () { return this.db.users();});একটি ভাগ করা অবজেক্ট হল একটি ফাংশন যা এটি ফেরত দেয় এবং একজন হ্যান্ডলার Depends এর সাথে এটির জন্য জিজ্ঞাসা করে:
class Db: def users(self) -> list[dict]: return [{"name": "Ada"}] db = Db() def get_db() -> Db: return dbfrom nexy.http import Depends from src.db import Db, get_db async def GET(db: Db = Depends(get_db)): return db.users()একটি পরীক্ষা এটি app.dependency_overrides[get_db] এর সাথে অদলবদল করে।
@fastify/cors, @fastify/compress, @fastify/cookie
await app.register(import("@fastify/cors"), { origin: "https://example.com" });await app.register(import("@fastify/compress"));from nexy.core.models import NexyConfigModel class NexyConfig(NexyConfigModel): useCORS = {"allow_origins": ["https://example.com"]} useGZip = {"minimum_size": 1000}একটি কুকির কোনো প্লাগইন লাগে না: এটি একটি Cookie প্যারামিটার দিয়ে পড়ুন, response.set_cookie দিয়ে সেট করুন।
from nexy.http import Cookie async def GET(theme: str = Cookie("light")): return {"theme": theme}setErrorHandler এবং setNotFoundHandler
app.setNotFoundHandler((request, reply) => reply.code(404).type("text/html").send("<h1>Not found</h1>"));ব্রাউজার পায় notfound.nexy, API ক্লায়েন্ট {"detail": "Not Found"}:
<h1>Not found</h1>একজন হ্যান্ডলার যে জানে কি ভুল হয়েছে তা উত্থাপন করে:
from nexy.http import HTTPException async def GET(id: int): if id > 100: raise HTTPException(status_code=404, detail="No such order") return {"id": id}@fastify/static
await app.register(import("@fastify/static"), { root: path.join(__dirname, "public") });লেখার কিছু নেই: public/ / এ পরিবেশিত হয়।
@fastify/websocket
await app.register(import("@fastify/websocket")); app.get("/ws/echo", { websocket: true }, (socket) => { socket.on("message", (message) => socket.send(message));});from fastapi import WebSocket async def SOCKET(websocket: WebSocket): await websocket.accept() await websocket.send_text(await websocket.receive_text())@fastify/swagger
await app.register(import("@fastify/swagger"));await app.register(import("@fastify/swagger-ui"), { routePrefix: "/docs" });নিবন্ধন করার জন্য কিছুই নেই: OpenAPI স্কিমা টাইপ টীকা থেকে তৈরি করা হয় এবং /docs এ পরিবেশিত হয়।
সঙ্গে পরীক্ষা inject
const response = await app.inject({ method: "GET", url: "/api/hello" });expect(response.json()).toEqual({ message: "Hello" });TestClient অ্যাপ্লিকেশনটিকে মেমরিতেও কল করে, কোনো পোর্ট ছাড়াই:
from fastapi.testclient import TestClient from nexy.app import app def test_hello(): assert TestClient(app).get("/api/hello").json() == {"message": "Hello"}চলছে
| দৃঢ় করা | নেক্সি |
|---|---|
npm init fastify |
nx new |
fastify start -w app.js |
nx dev |
node server.js উৎপাদনে |
nx build, তারপর nx start |
npm test |
nx test |