إنتقل إلى المحتوى الرئيسي

بناء واجهات برمجة التطبيقات باستخدام Cursor: REST وGraphQL وFastAPI

Cursor API Development

يتطلب بناء واجهات برمجة التطبيقات القوية تخطيطًا دقيقًا وأنماطًا متسقة واختبارًا دقيقًا. يمكن لقدرات الذكاء الاصطناعي في Cursor تسريع جميع مراحل تطوير واجهات برمجة التطبيقات، من إنشاء نقاط النهاية إلى توليد توثيق OpenAPI. يغطي هذا الدليل سير عمل REST وGraphQL وFastAPI.

المتطلبات الأساسية​

قبل البدء، ستحتاج إلى:

  • تثبيت Cursor مع خطة Pro (موصى به)
  • تثبيت Node.js أو Python
  • فهم مفاهيم HTTP وJSON

تطوير واجهة برمجة تطبيقات REST​

إنشاء هيكل المشروع​

اطلب من Cursor إنشاء هيكل REST API كامل:

أنشئ واجهة برمجة تطبيقات REST باستخدام Express.js تتضمن:
- TypeScript
- معالجات التوجيه في src/routes/
- وسائط للتسجيل ومعالجة الأخطاء
- التحقق من صحة الإدخال باستخدام Zod
- مصادقة JWT
- تقييد المعدل
- توثيق Swagger

هيكل توجيه Express.js​

// src/routes/users.ts
import { Router } from 'express';
import { z } from 'zod';
import { authenticate } from '../middleware/auth';
import { validate } from '../middleware/validate';

const router = Router();

const createUserSchema = z.object({
email: z.string().email(),
name: z.string().min(2).max(100),
password: z.string().min(8),
});

router.post(
'/',
authenticate,
validate(createUserSchema),
async (req, res, next) => {
try {
const user = await createUser(req.body);
res.status(201).json({
success: true,
data: user,
});
} catch (error) {
next(error);
}
}
);

router.get('/:id', authenticate, async (req, res, next) => {
try {
const user = await getUserById(req.params.id);
if (!user) {
return res.status(404).json({
success: false,
error: 'User not found',
});
}
res.json({ success: true, data: user });
} catch (error) {
next(error);
}
});

export default router;

معالجة الأخطاء المتكاملة​

// src/middleware/errorHandler.ts
import { Request, Response, NextFunction } from 'express';

export class AppError extends Error {
constructor(
public statusCode: number,
public message: string,
public isOperational = true
) {
super(message);
Object.setPrototypeOf(this, AppError.prototype);
}
}

export const errorHandler = (
err: Error,
req: Request,
res: Response,
next: NextFunction
) => {
if (err instanceof AppError) {
return res.status(err.statusCode).json({
success: false,
error: err.message,
});
}

console.error('Unexpected error:', err);
res.status(500).json({
success: false,
error: 'Internal server error',
});
};

تطوير FastAPI باستخدام Cursor​

إنشاء نقاط نهاية FastAPI​

# main.py
from fastapi import FastAPI, HTTPException, Depends, status
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel, EmailStr
from typing import List, Optional
import uvicorn

app = FastAPI(
title="My API",
description="A production-ready API built with FastAPI",
version="1.0.0",
)

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

# نماذج Pydantic
class UserCreate(BaseModel):
email: EmailStr
name: str
password: str

class UserResponse(BaseModel):
id: int
email: str
name: str

class Config:
from_attributes = True

# تخزين مؤقت في الذاكرة (استبدله بقاعدة بيانات)
users_db = {}
user_counter = 0

@app.post(
"/users",
response_model=UserResponse,
status_code=status.HTTP_201_CREATED,
tags=["users"],
)
async def create_user(user: UserCreate):
global user_counter
user_counter += 1
new_user = {
"id": user_counter,
"email": user.email,
"name": user.name,
}
users_db[user_counter] = new_user
return new_user

@app.get(
"/users/{user_id}",
response_model=UserResponse,
tags=["users"],
)
async def get_user(user_id: int):
if user_id not in users_db:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found",
)
return users_db[user_id]

@app.get("/users", response_model=List[UserResponse], tags=["users"])
async def list_users(
skip: int = 0,
limit: int = 100,
):
return list(users_db.values())[skip : skip + limit]

if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)

حقن التبعيات​

# dependencies.py
from fastapi import Depends, HTTPException, status
from sqlalchemy.orm import Session
from database import SessionLocal

async def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()

async def get_current_user(token: str = Depends(oauth2_scheme)):
user = verify_token(token)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid authentication",
)
return user

# Usage
@app.get("/items")
async def read_items(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
return db.query(Item).filter(Item.owner_id == current_user.id).all()

تطوير واجهة برمجة تطبيقات GraphQL​

إعداد Apollo Server​

// src/schema.ts
import { gql } from 'apollo-server-express';

export const typeDefs = gql`
type User {
id: ID!
email: String!
name: String!
posts: [Post!]!
}

type Post {
id: ID!
title: String!
content: String!
author: User!
}

type Query {
users: [User!]!
user(id: ID!): User
posts: [Post!]!
post(id: ID!): Post
}

type Mutation {
createUser(email: String!, name: String!, password: String!): User!
createPost(title: String!, content: String!, authorId: ID!): Post!
}
`;

محللات باستخدام Cursor​

// src/resolvers.ts
export const resolvers = {
Query: {
users: async (_, __, { dataSources }) => {
return dataSources.userAPI.getAllUsers();
},
user: async (_, { id }, { dataSources }) => {
return dataSources.userAPI.getUserById(id);
},
},
User: {
posts: async (parent, _, { dataSources }) => {
return dataSources.postAPI.getPostsByAuthor(parent.id);
},
},
Mutation: {
createUser: async (_, args, { dataSources }) => {
return dataSources.userAPI.createUser(args);
},
},
};
تصميم مخطط GraphQL

استخدم Cursor لإنشاء مخططات GraphQL من مخطط قاعدة البيانات الخاص بك. الصق مخطط Prisma واطلب تعريفات الأنواع GraphQL المقابلة.

المصادقة والتفويض​

تنفيذ JWT​

// src/utils/jwt.ts
import jwt from 'jsonwebtoken';
import bcrypt from 'bcrypt';

const JWT_SECRET = process.env.JWT_SECRET!;
const SALT_ROUNDS = 12;

export const hashPassword = async (password: string): Promise<string> => {
return bcrypt.hash(password, SALT_ROUNDS);
};

export const comparePassword = async (
password: string,
hash: string
): Promise<boolean> => {
return bcrypt.compare(password, hash);
};

export const generateToken = (payload: object): string => {
return jwt.sign(payload, JWT_SECRET, { expiresIn: '24h' });
};

export const verifyToken = (token: string): any => {
return jwt.verify(token, JWT_SECRET);
};

أنماط الوسائط​

// src/middleware/rateLimit.ts
import rateLimit from 'express-rate-limit';

export const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: {
success: false,
error: 'Too many requests, please try again later',
},
standardHeaders: true,
legacyHeaders: false,
});

توثيق واجهة برمجة التطبيقات​

OpenAPI في FastAPI​

يقوم FastAPI بتوليد توثيق OpenAPI تلقائيًا. الوصول إليه عبر:

  • Swagger UI: /docs
  • ReDoc: /redoc

Express.js مع Swagger​

// src/config/swagger.ts
import swaggerJsdoc from 'swagger-jsdoc';

const options = {
definition: {
openapi: '3.0.0',
info: {
title: 'My API',
version: '1.0.0',
description: 'API documentation',
},
servers: [
{
url: 'http://localhost:3000/api',
},
],
},
apis: ['./src/routes/*.ts'],
};

export const specs = swaggerJsdoc(options);

اختبار واجهات برمجة التطبيقات​

مثال على اختبار التكامل​

// tests/users.test.ts
import request from 'supertest';
import app from '../src/app';

describe('Users API', () => {
describe('POST /users', () => {
it('should create a new user', async () => {
const response = await request(app)
.post('/users')
.send({
name: 'Test User',
password: 'securePassword123',
})
.expect(201);

expect(response.body.success).toBe(true);
expect(response.body.data.email).toBe('[email protected]');
});

it('should reject invalid email', async () => {
await request(app)
.post('/users')
.send({
email: 'invalid-email',
name: 'Test',
password: 'password',
})
.expect(400);
});
});
});

أفضل ممارسات تصميم واجهة برمجة التطبيقات​

الممارسةالتنفيذ
الإصداراستخدم البادئة /api/v1/ في URL
الترقيم الصفحيأرجع { data, meta: { page, limit, total } }
التصفيةاستخدام معلمات الاستعلام: ?status=active&sort=created_at
تنسيق الخطأمتسق { success: false, error: "message" }
تقييد المعدل100 طلب كل 15 دقيقة للنقاط النهائية العامة
التخزين المؤقتاستخدام رؤوس ETag وتخزين الاستجابة مؤقتًا مع Redis

أنماط واجهة برمجة التطبيقات الشائعة​

نمط المستودع​

// src/repositories/UserRepository.ts
export class UserRepository {
async findById(id: string): Promise<User | null> {
return prisma.user.findUnique({ where: { id } });
}

async findByEmail(email: string): Promise<User | null> {
return prisma.user.findUnique({ where: { email } });
}

async create(data: CreateUserInput): Promise<User> {
return prisma.user.create({ data });
}

async update(id: string, data: UpdateUserInput): Promise<User> {
return prisma.user.update({ where: { id }, data });
}

async delete(id: string): Promise<void> {
await prisma.user.delete({ where: { id } });
}
}

تكوين البيئة​

# .env
NODE_ENV=development
PORT=3000
DATABASE_URL=postgresql://user:pass@localhost:5432/myapp
JWT_SECRET=your-secret-key
REDIS_URL=redis://localhost:6379
RATE_LIMIT_MAX=100

مرجع سريع​

المهمةمطالبة Cursor
إنشاء نقاط نهاية CRUD"Create CRUD endpoints for a Product resource with validation"
إضافة مصادقة"Add JWT authentication middleware to all protected routes"
إنشاء مخطط GraphQL"Generate GraphQL types from this Prisma schema"
كتابة الاختبارات"Write integration tests for the user registration endpoint"
إضافة تقييد المعدل"Add rate limiting to the API with different tiers for auth vs public"

موارد ذات صلة​

آخر تحديث: يوليو 2025