مقدمه

در فصل گذشته، ما یک اپلیکیشن وب با استفاده از Razor Pages ساختیم که HTML را مستقیماً در سمت سرور تولید کرده و به مرورگر ارسال می‌کرد. این رویکرد برای وب‌سایت‌های سنتی عالی است. اما در دنیای مدرن، بسیاری از اپلیکیشن‌ها از یک معماری متفاوت پیروی می‌کنند: یک "بک‌اند" (backend) که فقط داده‌ها را (معمولاً در فرمت JSON) ارائه می‌دهد و یک یا چند "فرانت‌اند" (frontend) جداگانه (مانند یک اپلیکیشن تک‌صفحه‌ای (SPA) نوشته شده با React یا Angular، یا یک اپلیکیشن موبایل) که این داده‌ها را دریافت کرده و مسئولیت نمایش آن‌ها را بر عهده دارند.

برای ساختن این بک‌اندها، ما از ASP.NET Core Web API استفاده می‌کنیم. این فریم‌ورک به ما اجازه می‌دهد تا وب‌سرویس‌های HTTP بسازیم که از اصول معماری REST (Representational State Transfer) پیروی می‌کنند. در این درس، با مفاهیم اصلی Web API مانند کنترلرها، اکشن‌ها و مسیریابی آشنا شده و یک API ساده برای موجودیت Movie خود خواهیم ساخت.

کنترلرها و اکشن‌ها

واحد اصلی کار در یک Web API، کنترلر (Controller) است. یک کنترلر، کلاسی است که به طور منطقی، مجموعه‌ای از "اکشن‌ها" (actions) را گروه‌بندی می‌کند. هر اکشن، یک متد عمومی در کلاس کنترلر است که به یک درخواست HTTP خاص در یک آدرس (endpoint) مشخص پاسخ می‌دهد.

طبق قرارداد، کلاس‌های کنترلر از ControllerBase ارث‌بری می‌کنند، با صفت [ApiController] علامت‌گذاری می‌شوند و در پوشه‌ای به نام Controllers قرار می‌گیرند.

ساخت یک Web API Controller

مانند Razor Pages، ما می‌توانیم از ابزارهای Scaffolding برای تولید خودکار یک کنترلر API با تمام اکشن‌های CRUD استفاده کنیم.

  1. در Solution Explorer، روی پوشه‌ی Controllers راست‌کلیک کرده و گزینه‌ی AddController... را انتخاب کنید.
  2. در پنجره‌ی باز شده، API Controller with actions, using Entity Framework را انتخاب کنید.
  3. در پنجره‌ی بعدی، کلاس مدل (Movie) و کلاس DbContext (WebAppDbContext) را مشخص کرده و روی Add کلیک کنید.

ویژوال استودیو یک فایل جدید به نام MoviesController.cs با کدی شبیه به زیر ایجاد می‌کند.

Copy Icon MoviesController.cs (Simplified)
[Route("api/[controller]")]
[ApiController]
public class MoviesController : ControllerBase
{
    private readonly WebAppDbContext _context;

    public MoviesController(WebAppDbContext context)
    {
        _context = context;
    }

    // GET: api/Movies
    [HttpGet]
    public async Task<ActionResult<IEnumerable<Movie>>> GetMovies()
    {
        return await _context.Movie.ToListAsync();
    }

    // GET: api/Movies/5
    [HttpGet("{id}")]
    public async Task<ActionResult<Movie>> GetMovie(int id)
    {
        var movie = await _context.Movie.FindAsync(id);

        if (movie == null)
        {
            return NotFound();
        }

        return movie;
    }
    
    // POST: api/Movies
    [HttpPost]
    public async Task<ActionResult<Movie>> PostMovie(Movie movie)
    {
        _context.Movie.Add(movie);
        await _context.SaveChangesAsync();

        return CreatedAtAction("GetMovie", new { id = movie.Id }, movie);
    }

    // Other actions (PUT, DELETE) ...
}

تحلیل کد کنترلر

  • [Route("api/[controller]")]: این صفت، الگوی مسیر پایه را برای تمام اکشن‌های این کنترلر تعریف می‌کند. [controller] یک توکن است که با نام کنترلر (بدون پسوند "Controller") جایگزین می‌شود. بنابراین، آدرس پایه‌ی این کنترلر /api/Movies خواهد بود.
  • [ApiController]: این صفت مجموعه‌ای از رفتارها و قراردادهای مفید را برای کنترلرهای API فعال می‌کند، مانند اتصال خودکار مدل از بدنه‌ی درخواست و بازگرداندن پاسخ‌های خطای استاندارد.
  • تزریق وابستگی: درست مانند Razor Pages، ما WebAppDbContext را از طریق سازنده تزریق می‌کنیم تا به پایگاه داده دسترسی داشته باشیم.
  • صفت‌های فعل HTTP: هر اکشن با یک صفت مانند [HttpGet]، [HttpPost]، [HttpPut] یا [HttpDelete] علامت‌گذاری می‌شود. این صفت‌ها مشخص می‌کنند که اکشن به کدام فعل HTTP پاسخ می‌دهد.
  • مسیریابی اکشن: صفت [HttpGet("{id}")] مشخص می‌کند که این اکشن به درخواست‌های GET به آدرسی مانند /api/Movies/5 پاسخ می‌دهد و مقدار 5 به پارامتر id متد متصل خواهد شد.
  • مقادیر بازگشتی: اکشن‌ها معمولاً یک ActionResult<T> برمی‌گردانند. این به آن‌ها اجازه می‌دهد تا هم داده‌ی مورد نظر (مانند یک شیء Movie) و هم کدهای وضعیت HTTP مختلف (مانند Ok()، NotFound()، BadRequest()) را برگردانند. برای مثال، متد CreatedAtAction یک پاسخ `201 Created` را به همراه آدرس منبع جدید و خود شیء ایجاد شده، برمی‌گرداند که یک رویه‌ی استاندارد در REST است.

تست کردن Web API

شما می‌توانید API خود را مستقیماً از طریق مرورگر (برای درخواست‌های GET) یا با استفاده از ابزارهای تخصصی مانند Postman یا Swagger UI تست کنید. پروژه‌های Web API در ASP.NET Core به طور پیش‌فرض شامل پشتیبانی از Swagger (OpenAPI) هستند که یک صفحه‌ی وب تعاملی برای مستندسازی و تست تمام نقاط پایانی API شما تولید می‌کند.