آموزش REST API در سی‌شارپ (#C) برای مبتدیان

REST API , c# مبتدی
parsakarimidev.ir

آموزش REST API در سی‌شارپ (#C) برای مبتدیان

REST API , c#زبان برنامه‌نویسی سطح: مبتدی 1405/07/03

آموزش REST API در سی‌شارپ (#C) برای مبتدیان

⚡ خلاصه سریع — اصل کاری‌ها

این‌ها مهم‌ترین چیزهایی هستن که اگه هیچی ندونی، فقط اینا رو بدونی کافیه:

  • REST API یعنی مجموعه‌ای از آدرس‌های HTTP که داده رو بین کلاینت و سرور جابجا می‌کنن.
  • HTTP Method نوع عملیات رو مشخص می‌کنه: GET خواندن، POST ساخت، PUT ویرایش کامل، DELETE حذف.
  • Route مثل آدرس خیابونه؛ مثلاً /products به لیست محصولات اشاره می‌کنه.
  • JSON زبان مشترک تبادل داده‌ست؛ در C# با record یا class مدل می‌سازی.
  • Status Code نتیجه کار رو نشون می‌ده: 200 موفقیت، 201 ساخته شد، 404 پیدا نشد، 400 خطای کاربر.
  • Minimal API ساده‌ترین روش ساخت REST API در ASP.NET Core جدیده.
  • DTO داده‌ای که به کاربر نمایش می‌دی؛ نباید اطلاعات حساس یا مدل دیتابیس رو مستقیم بفرستی.

۳ اشتباه رایج که باید ازشون پرهیز کنی:

  1. استفاده از فعل توی آدرس (مثل /getProducts) به‌جای اسم جمع (/products).
  2. برگردوندن 200 برای همه چیز حتی وقتی خطا رخ داده.
  3. فرستادن مدل‌های دیتابیس مستقیم به کاربر به‌جای DTO.

اگر فقط ۵ دقیقه وقت داری، این‌ها رو یاد بگیر:

  1. REST یعنی هر URL یک منبع (Resource) است و HTTP Method عملیات روی اون رو مشخص می‌کنه.
  2. GET /products یعنی لیست، POST /products یعنی ساخت، DELETE /products/{id} یعنی حذف.
  3. برای شروع: dotnet new webapi -n MyApi و بعدش با app.MapGet(...) اولین endpoint رو بساز.

۱. مقدمه

REST API یک سبک معماری برای ارتباط بین سیستم‌ها از طریق HTTP است. در دنیای #C، این کار با ASP.NET Core Web API انجام می‌شه.

  • این موضوع چیه؟
    REST API یعنی مجموعه‌ای از endpoint ها (آدرس‌های HTTP) که داده‌ها رو در قالب JSON جابجا می‌کنن. مثلاً وقتی اپلیکیشن موبایل می‌خواد لیست محصولات رو بگیره، به آدرس /products درخواست GET می‌فرسته و سرور لیست رو برمی‌گردونه.

  • چرا باید یادش بگیری؟
    تقریباً هر برنامه مدرنی (وب، موبایل، دسکتاپ) برای ذخیره و بازیابی اطلاعات به یک API نیاز داره. اگر بتونی REST API بسازی، می‌تونی پشتیبان هر نوع کلاینتی باشی.

  • کجا استفاده می‌شه؟

    • اپلیکیشن‌های موبایل (اندروید، iOS)
    • وب‌سایت‌های SPA مثل React و Angular
    • سیستم‌های میکروسرویسی
    • ارتباط بین سیستم‌های مختلف سازمانی

۲. پیش‌نیازها

قبل از شروع، این‌ها رو باید بدونی:

  • زبان C# مقدماتی: متغیر، کلاس، متد، List، LINQ ساده مثل FirstOrDefault.
  • مفاهیم HTTP: آشنایی با درخواست و پاسخ، متدهای GET و POST.
  • JSON: بدونی JSON چطور ساختار داده رو نشون می‌ده. مثلاً:
{ "id": 1, "name": "Laptop" }

ابزارهای لازم:

  • .NET SDK نسخه ۶ یا ۸ (ترجیحاً ۸)
  • Visual Studio 2022 یا VS Code با افزونه C#
  • Postman یا استفاده از Swagger برای تست API (در پروژه Web API خودش Swagger داره)

۳. نصب و راه‌اندازی

گام ۱ — نصب .NET SDK

از سایت رسمی dotnet.microsoft.com دانلود و نصب کن. بعد از نصب، ترمینال رو باز کن و تایپ کن:

dotnet --version

اگه شماره نسخه رو دیدی، یعنی همه‌چیز آماده‌ست.

گام ۲ — ساخت اولین پروژه

در ترمینال دستور زیر رو بزن:

dotnet new webapi -n MyFirstApi

این دستور یک پروژه ASP.NET Core Web API با نام MyFirstApi می‌سازه.

گام ۳ — رفتن به پوشه پروژه

cd MyFirstApi

گام ۴ — اجرای پروژه

dotnet run

بعد از اجرا، خروجی چیزی شبیه اینه:

info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5000

حالا می‌تونی در مرورگر آدرس http://localhost:5000/swagger رو باز کنی تا Swagger UI رو ببینی. Swagger به صورت خودکار لیست endpoint ها رو نشون می‌ده و می‌تونی از اونجا تستشون کنی.

گام ۵ — اولین تغییر ساده

فایل Program.cs رو باز کن. می‌تونی endpoint پیش‌فرض رو حذف کنی و یک endpoint ساده برای تست بسازی. این کار رو در بخش بعد انجام می‌دیم.

۴. مفاهیم پایه

۴.۱ Resource (منبع)

هر چیزی که API در اختیار می‌ذاره یک Resource است. به‌طور معمول با یک اسم جمع در URL مشخص می‌شه:

  • /products → لیست محصولات
  • /products/1 → محصول با شناسه ۱
  • /customers → لیست مشتریان

۴.۲ HTTP Methods (افعال HTTP)

مهم‌ترین متدها:

متد کاربرد مثال
GET خواندن داده GET /products
POST ساخت داده جدید POST /products
PUT ویرایش کامل داده PUT /products/1
DELETE حذف داده DELETE /products/1

۴.۳ Route و Route Parameters

Route همان آدرس endpoint است. برای دسترسی به یک آیتم خاص، از پارامتر داخل آدرس استفاده می‌کنیم:

app.MapGet("/products/{id}", (int id) => ...);

در اینجا {id} یک پارامتر مسیر است و مقدارش از URL خوانده می‌شه.

۴.۴ JSON و Model Binding

درخواست‌ها و پاسخ‌ها معمولاً JSON هستن. ASP.NET Core به‌طور خودکار بدنه JSON درخواست رو به مدل C# تبدیل می‌کنه (Model Binding). مثلاً وقتی کلاینتی این JSON رو بفرسته:

{ "id": 3, "name": "Mouse", "price": 25.5 }

و endpoint به این شکل باشه:

app.MapPost("/products", (Product product) => ...);

خودش یک Product با مقادیر پر شده تحویل می‌گیره.

۴.۵ Status Codes (کدهای وضعیت)

کد وضعیت HTTP نتیجه عملیات رو نشون می‌ده:

  • 200 OK — موفقیت
  • 201 Created — ساخته شد
  • 204 No Content — موفقیت بدون خروجی (مثل حذف)
  • 400 Bad Request — خطای کاربر
  • 404 Not Found — پیدا نشد
  • 500 Internal Server Error — خطای سرور

در Minimal API از کلاس Results برای برگرداندن این کدها استفاده می‌کنیم.

۵. مثال‌های کد ساده

۵.۱ ساده‌ترین endpoint

فایل Program.cs را با این کد جایگزین کن:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

با اجرا و باز کردن http://localhost:5000/ متن Hello World! را می‌بینی.

۵.۲ ساخت یک API کامل برای محصولات

حالا یک مدل، یک لیست در حافظه و endpoint های CRUD می‌سازیم.

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// مدل ساده محصول
record Product(int Id, string Name, decimal Price);

// دیتابیس موقت در حافظه
var products = new List<Product>
{
    new(1, "Laptop", 1200),
    new(2, "Phone", 800)
};

// GET /products -> لیست همه محصولات
app.MapGet("/products", () => Results.Ok(products));

// GET /products/{id} -> یک محصول خاص
app.MapGet("/products/{id}", (int id) =>
{
    var product = products.FirstOrDefault(p => p.Id == id);
    return product is null
        ? Results.NotFound($"محصول {id} پیدا نشد")
        : Results.Ok(product);
});

// POST /products -> ساخت محصول جدید
app.MapPost("/products", (Product product) =>
{
    products.Add(product);
    return Results.Created($"/products/{product.Id}", product);
});

// PUT /products/{id} -> ویرایش کامل محصول
app.MapPut("/products/{id}", (int id, Product updatedProduct) =>
{
    var index = products.FindIndex(p => p.Id == id);
    if (index == -1)
        return Results.NotFound();

    products[index] = updatedProduct with { Id = id };
    return Results.NoContent();
});

// DELETE /products/{id} -> حذف محصول
app.MapDelete("/products/{id}", (int id) =>
{
    var product = products.FirstOrDefault(p => p.Id == id);
    if (product is null)
        return Results.NotFound();

    products.Remove(product);
    return Results.NoContent();
});

app.Run();

توضیح کد:

  • record Product یک مدل ساده با سه ویژگی.
  • products یک لیست در حافظه که نقش دیتابیس موقت رو داره.
  • MapGet, MapPost, MapPut, MapDelete endpoint ها رو تعریف می‌کنن.
  • Results.Ok, Results.NotFound, Results.Created, Results.NoContent کدهای وضعیت مناسب رو برمی‌گردونن.
  • updatedProduct with { Id = id } یک کپی از محصول جدید می‌سازه و شناسه رو ثابت نگه می‌داره.

۵.۳ تست با Swagger یا Postman

پروژه رو اجرا کن و به http://localhost:5000/swagger برو. می‌تونی تمام endpoint ها رو از آنجا تست کنی.

۶. مثال واقعی و کاربردی — ساخت API مدیریت کارها (To-Do List)

حالا یک پروژه کوچیک واقعی می‌سازیم: Todo API با قابلیت اضافه، نمایش، ویرایش و حذف کارها.

گام ۱ — ساخت پروژه

dotnet new webapi -n TodoApi
cd TodoApi

گام ۲ — جایگزینی کد Program.cs

فایل Program.cs را با کد زیر جایگزین کن:

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// مدل کار
record TodoItem(int Id, string Title, bool IsComplete);

// لیست در حافظه
var todos = new List<TodoItem>
{
    new(1, "Learn REST API", true),
    new(2, "Build a project", false)
};

// GET /todos -> لیست همه کارها
app.MapGet("/todos", () => Results.Ok(todos));

// GET /todos/{id} -> یک کار خاص
app.MapGet("/todos/{id}", (int id) =>
{
    var todo = todos.FirstOrDefault(t => t.Id == id);
    return todo is null ? Results.NotFound() : Results.Ok(todo);
});

// POST /todos -> ایجاد کار جدید
app.MapPost("/todos", (TodoItem newTodo) =>
{
    todos.Add(newTodo);
    return Results.Created($"/todos/{newTodo.Id}", newTodo);
});

// PUT /todos/{id} -> ویرایش کامل
app.MapPut("/todos/{id}", (int id, TodoItem updatedTodo) =>
{
    var index = todos.FindIndex(t => t.Id == id);
    if (index == -1) return Results.NotFound();

    todos[index] = updatedTodo with { Id = id };
    return Results.NoContent();
});

// DELETE /todos/{id} -> حذف
app.MapDelete("/todos/{id}", (int id) =>
{
    var todo = todos.FirstOrDefault(t => t.Id == id);
    if (todo is null) return Results.NotFound();

    todos.Remove(todo);
    return Results.NoContent();
});

app.Run();

گام ۳ — اجرا و تست

dotnet run

سپس به http://localhost:5000/swagger برو و درخواست‌ها رو تست کن.

مثال درخواست POST:

{
  "id": 3,
  "title": "Review PR",
  "isComplete": false
}

پاسخ:

{
  "id": 3,
  "title": "Review PR",
  "isComplete": false
}

این یک پروژه ساده ولی کامل REST API است.

۷. مباحث پیشرفته

بعد از یادگیری مباحث پایه، این تکنیک‌ها رو باید بشناسی:

۷.۱ Dependency Injection (تزریق وابستگی)

به‌جای اینکه همه‌چیز رو داخل endpoint بنویسی، سرویس‌ها رو جدا می‌سازی و از طریق DI تزریق می‌کنی. مثال:

builder.Services.AddSingleton<IProductService, ProductService>();

app.MapGet("/products", (IProductService service) =>
{
    return Results.Ok(service.GetAll());
});

۷.۲ Entity Framework Core

برای کار با دیتابیس واقعی، از EF Core استفاده می‌کنیم:

app.MapGet("/todos", async (AppDbContext db) =>
{
    return Results.Ok(await db.Todos.ToListAsync());
});

۷.۳ Asynchronous Programming

همیشه برای عملیات I/O (دیتابیس، فایل، شبکه) از async/await استفاده کن تا سرور قفل نشه:

app.MapGet("/todos", async (AppDbContext db) =>
    await db.Todos.ToListAsync()
);

۷.۴ Validation (اعتبارسنجی)

از Data Annotations برای اعتبارسنجی ورودی استفاده کن:

public record ProductDto
{
    [Required]
    public string Name { get; init; }
    [Range(0.01, double.MaxValue)]
    public decimal Price { get; init; }
}

۷.۵ API Versioning

برای API های عمومی، نسخه‌بندی اهمیت داره:

app.MapGet("/api/v1/products", ...);
app.MapGet("/api/v2/products", ...);

۷.۶ Authentication / Authorization

برای محافظت از API از JWT یا OAuth استفاده کن. در ASP.NET Core با [Authorize] روی endpoint ها اعمال می‌شه.

۸. اشتباهات رایج

مبتدی‌ها اغلب این اشتباهات رو مرتکب می‌شن:

  1. استفاده از فعل در URL
    اشتباه: GET /getProducts
    درست: GET /products

  2. برگردوندن 200 برای همه چیز
    حتی وقتی چیزی پیدا نشده، 200 برمی‌گردونن.
    درست: اگر پیدا نشد 404 NotFound.

  3. نادیده گرفتن DTO
    مدل دیتابیس رو مستقیم به کاربر برمی‌گردونن.
    درست: برای نمایش، فقط داده‌های لازم رو در یک DTO بفرست.

  4. بلاک کردن async
    استفاده از .Result یا .Wait() روی متدهای async باعث قفل شدن سرور می‌شه.
    درست: از await استفاده کن.

  5. عدم اعتبارسنجی ورودی
    هر داده‌ای از کاربر رو قبول می‌کنن.
    درست: همیشه ورودی رو اعتبارسنجی کن.

  6. استفاده از PUT برای تغییر جزئی
    PUT برای ویرایش کامل است. اگر فقط یک فیلد تغییر می‌کنه، از PATCH استفاده کن.

۹. بهترین روش‌ها (Best Practices)

  • از اسم جمع برای Resource استفاده کن: /products به‌جای /product.
  • کد وضعیت مناسب برگردون: موفقیت، خطا، پیدا نشد و... .
  • همیشه DTO بساز: هیچ‌وقت مدل دیتابیس رو مستقیم برنگردون.
  • از async/await استفاده کن.
  • ورودی‌ها رو اعتبارسنجی کن.
  • از Swagger برای مستندسازی خودکار استفاده کن.
  • نام‌گذاری یکدست داشته باش.
  • خطاهای سرور رو پنهان کن: هرگز stack trace رو به کلاینت نده.
  • برای API های عمومی از Versioning استفاده کن.
  • بتدریج به سمت معماری Clean Architecture حرکت کن.

۱۰. منابع و ادامه مسیر

  • مایکروسافت لرن (Microsoft Learn): دوره «Create a web API with ASP.NET Core» — رایگان و رسمی.
  • مستندات رسمی ASP.NET Core: learn.microsoft.com/aspnet/core
  • کتاب: «ASP.NET Core in Action» نوشته Andrew Lock — عالی برای عمیق‌تر شدن.
  • کانال‌های یوتیوب فارسی: جستجوی «آموزش REST API با ASP.NET Core» کلی محتوای خوب داره.
  • تمرین: سعی کن یک API برای دفترچه تلفن یا سیستم کتابخانه بسازی و با Postman تست کنی.

مسیر بعدی: بعد از تسلط بر Minimal API، سراغ Controller ها، Entity Framework Core و بعد معماری‌های تمیزتر مثل CQRS یا Clean Architecture برو.

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.