ডকুমেন্টেশনফুলস্ট্যাক ফ্রেমওয়ার্ক
লারাভেল থেকে নেক্সি পর্যন্ত
নেক্সিতে একটি লারাভেল রুট এবং এর কন্ট্রোলার পদ্ধতি src/routes/ এর অধীনে একটি ফাইল হয়ে যায়: একটি ব্লেড ভিউ একটি .nexy পৃষ্ঠা, $request->validate একটি Pydantic মডেল, এবং আপনার বেছে নেওয়া একটি ওআরএম যেমন SQLModel।
নীচের প্রতিটি বিভাগ একটি Laravel অভ্যাস দেখায়, তারপর Nexy তে একই জিনিস।
একটি রুট
use Illuminate\Support\Facades\Route; Route::get('/hello', fn () => ['message' => 'Hello']);কোন রুট ফাইল নেই: ফাইল পাথ হল URL, এবং ফাংশনের নাম হল পদ্ধতি।
async def GET(): return {"message": "Hello"}রুট প্যারামিটার এবং where
Route::get('/users/{id}', fn (int $id) => ['id' => $id])->whereNumber('id');{id} হল একটি [id] সেগমেন্ট, এবং int টীকা হল সীমাবদ্ধতা: /api/users/abc উত্তর দেয় 404।
async def GET(id: int): return {"id": id}একটি ঐচ্ছিক {slug?} বা একটি {path} ম্যাচিং স্ল্যাশ (->where('path', '.*')) হল একটি [...path].py ক্যাচ-অল।
কন্ট্রোলার
class NoteController extends Controller{ public function show(int $id) { return ['id' => $id]; } public function destroy(int $id) { return ['deleted' => $id]; }}Route::get('/notes/{id}', [NoteController::class, 'show']);Route::delete('/notes/{id}', [NoteController::class, 'destroy']);কন্ট্রোলার পদ্ধতি হল ফাইলের ফাংশন, ক্রিয়াটির নামকরণ করা হয়েছে:
async def GET(id: int): return {"id": id} async def DELETE(id: int): return {"deleted": id}লারাভেল কন্ট্রোলারের মতো ইনজেকশন পরিষেবা সহ ক্লাসের জন্য, মডুলার রাউটার দেখুন।
প্রশ্ন স্ট্রিং
public function __invoke(Request $request){ return ['q' => $request->query('q', ''), 'page' => (int) $request->query('page', 1)];}async def GET(q: str = "", page: int = 1): return {"q": q, "page": page}বৈধতা এবং ফর্ম অনুরোধ
public function store(Request $request){ $data = $request->validate([ 'name' => 'required|string|max:100', 'price' => 'required|numeric|gt:0', ]); return response()->json($data, 201);}নিয়ম একটি Pydantic মডেল। একটি শরীর যা একজনকে ক্ষেত্র এবং নিয়মের সাথে উত্তর দেয় 422, যেমন লারাভেল করে:
from pydantic import BaseModel, Field from nexy.http import JSONResponse class NewItem(BaseModel): name: str = Field(max_length=100) price: float = Field(gt=0) async def POST(item: NewItem): return JSONResponse(item.model_dump(), status_code=201)একটি উপসর্গ এবং মিডলওয়্যার সহ রুট গ্রুপ
Route::prefix('admin')->middleware('admin')->group(function () { Route::get('/stats', fn () => ['users' => 3]);});public function handle(Request $request, Closure $next){ abort_unless($request->header('X-Role') === 'admin', 403, 'Admins only'); return $next($request);}ফোল্ডারটি হল উপসর্গ, এবং এর dependencies.py হল গ্রুপের মিডলওয়্যার:
async def GET(): return {"users": 3}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]গ্লোবাল মিডলওয়্যার
public function handle(Request $request, Closure $next){ $response = $next($request); $response->headers->set('X-App', 'demo'); return $response;}রুট রুটে একটি 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 responseব্লেড ভিউ
Route::get('/users', fn () => view('users', ['users' => [['name' => 'Ada'], ['name' => 'Alan']]]));@extends('layouts.app') @section('content')<ul> @foreach ($users as $user) <li>{{ $user['name'] }}</li> @endforeach</ul>@endsectionরুট এবং ভিউ একটি .nexy ফাইল:
users = [{"name": "Ada"}, {"name": "Alan"}]<ul> {% for user in users %} <li>{{ user.name }}</li> {% endfor %}</ul>| ব্লেড | Jinja2 .nexy মধ্যে |
|---|---|
{{ $name }} (পলায়ন) |
{{ name | e }}: .nexy ডিফল্টরূপে অব্যাহতি পায় না |
{!! $html !!} |
{{ html | safe }} |
@if ($user) ... @endif |
{% if user %} ... {% endif %} |
@foreach ($items as $item) |
{% for item in items %} |
@php ... @endphp |
Python ফ্রন্ট ম্যাটারে |
বিন্যাস এবং @yield
<!DOCTYPE html><html> <body>@yield('content')</body></html>একটি layout.nexy তার ফোল্ডারের প্রতিটি পৃষ্ঠাকে মুড়ে দেয়, পৃষ্ঠাগুলিতে @extends নেই:
children: prop[NexyElement]<!DOCTYPE html><html> <body>{{ children | safe }}</body></html>ব্লেড উপাদান
@props(['title'])<article> <h2>{{ $title }}</h2> {{ $slot }}</article><x-card title="Latest"><p>This week</p></x-card>
title: prop[str]<article> <h2>{{ title }}</h2> <Slot /></article>from "@/components/Card.nexy" import Card<Card title="Latest"> <p>This week</p></Card>@ হল src/: nx new লিখেছেন useAliases = {"@": "src"} nexyconfig.py।
ফর্ম, @csrf এবং পুনঃনির্দেশ
<form method="POST" action="{{ route('notes.store') }}"> @csrf <input name="title"> <button type="submit">Add</button></form>public function store(Request $request){ Note::create($request->validate(['title' => 'required'])); return back();}একটি কর্ম হল নিয়ামক পদ্ধতি যা ফর্ম পোস্ট করে। এর পরামিতিগুলি হল ক্ষেত্র, এবং দর্শক সাফল্যের উপর 303 সহ back() যায়:
from nexy.decorators import Action NOTES: list[str] = [] @Actionasync def add_note(title: str) -> None: NOTES.append(title)from src.actions.notes import NOTES<form method="post" action="{{ __actions_path['add_note'] }}"> <input name="title"> <button type="submit">Add</button></form><ul> {% for note in NOTES %} <li>{{ note }}</li> {% endfor %}</ul>বাগ্মী এবং দেশান্তর
class Post extends Model{ protected $fillable = ['title', 'published'];} $posts = Post::where('published', true)->get();Nexy এর নিজস্ব কোন ORM নেই। nx new ভারা হতে পারে SQLModel, SQLAlchemy বা কচ্ছপ-ORM; সঙ্গে SQLModel:
from sqlmodel import Field, SQLModel class Post(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) title: str published: bool = Falsefrom sqlmodel import Session, select from src.configs.db import enginefrom src.models.post_model import Post async def GET(): with Session(engine) as session: posts = session.exec(select(Post).where(Post.published)).all() return {"titles": [post.title for post in posts]}| কারিগর | নেক্সি |
|---|---|
php artisan make:migration |
nx migrate -m "add posts" |
php artisan migrate |
nx migrate --upgrade |
ডেটাবেস দেখুন।
abort(404) এবং ত্রুটি দেখা
Route::get('/posts/{slug}', function (string $slug) { abort_unless(isset(POSTS[$slug]), 404); return view('post', ['post' => POSTS[$slug]]);});notFound() হল abort(404), এবং notfound.nexy হল resources/views/errors/404.blade.php:
from nexy import notFound POSTS = {"hello": "Hello, world"} slug: prop[str]if slug not in POSTS: notFound()<h1>{{ POSTS[slug] }}</h1><h1>Not found</h1>সেশন
public function store(Request $request){ session(['user' => $request->input('name')]); return ['user' => session('user')];}from nexy.core.models import NexyConfigModel class NexyConfig(NexyConfigModel): useAliases = {"@": "src"} useSession = {"secret_key": "change-me"}from pydantic import BaseModel from nexy.http import Request class Login(BaseModel): name: str async def POST(request: Request, body: Login): request.session["user"] = body.name return {"user": body.name}একটি পৃষ্ঠা useSession() সহ অধিবেশনটি পড়ে।
সারি এবং dispatch
SendWelcomeEmail::dispatch($user); return response()->json(['queued' => true], 202);উত্তরের পরে চলতে পারে এমন কাজের জন্য, FastAPI এর ব্যাকগ্রাউন্ডের কাজগুলি যথেষ্ট:
from nexy.http import BackgroundTasks, JSONResponse SENT: list[str] = [] def send_welcome_email(email: str) -> None: SENT.append(email) async def POST(email: str, tasks: BackgroundTasks): tasks.add_task(send_welcome_email, email) return JSONResponse({"queued": True}, status_code=202)অন্য মেশিনে পুনরায় চেষ্টা এবং কর্মীদের জন্য, সেলারি, আরকিউ বা আরকিউর মতো একটি Python সারি ব্যবহার করুন।
একটি পৃষ্ঠা ক্যাশে করা হচ্ছে
Route::get('/blog', BlogController::class)->middleware('cache.headers:public;max_age=60');
revalidate = 60<h1>Blog</h1>পৃষ্ঠাটি প্রতি URL ক্যাশে করা হয় এবং 60 সেকেন্ড পরে পটভূমিতে আবার রেন্ডার করা হয়।
.env এবং config/
| লারাভেল | নেক্সি |
|---|---|
.env + config/database.php |
.env DATABASE_URL সহ, src/configs/db.py দ্বারা পঠিত |
config/cors.php |
useCORS nexyconfig.py এ |
APP_KEY সেশনের জন্য |
useSession = {"secret_key": ...} |
public/ |
public/, / এ পরিবেশিত |
লাইভওয়্যার এবং জড়তা
লাইভওয়্যারের সার্ভার-চালিত উপাদানগুলি একটি পৃষ্ঠা থেকে কল করা ক্রিয়াগুলির মানচিত্র করে। Inertia এর React বা Vue পৃষ্ঠাগুলি .tsx বা .vue রুটে, অথবা .nexy পৃষ্ঠার ভিতরের দ্বীপগুলির মানচিত্র। কর্ম এবং দ্বীপগুলি দেখুন।
টেস্ট
public function test_hello(): void{ $this->getJson('/api/hello')->assertExactJson(['message' => 'Hello']);}from fastapi.testclient import TestClient from nexy.app import app def test_hello(): assert TestClient(app).get("/api/hello").json() == {"message": "Hello"}চলছে
| লারাভেল | নেক্সি |
|---|---|
laravel new |
nx new |
php artisan serve |
nx dev |
php artisan route:list |
/docs |
php artisan test |
nx test |
npm run build |
nx build |