آموزش OData در asp core 5

آموزش پیاده سازی OData در AspNet Core 5

تخمین مدت زمان مطالعه : 7 دقیقه
  • سطح مقاله : متوسطه
  • نویسنده : پوریا منتخب

 OData چیست ؟

به گفته طراحان اون، OData (the Open Protocol Data)  بهترین روش استفاده از REST  است. OData  روشی ضروری برای تست و استانداردسازی API  های REST است.OData  یک پروتکل باز (مجموعه ای از برنامه ها و روش ها که منطبق بر یک استاندارد فراگیر شدن و این استاندارد مورد تایید بسیاری از تولیدکنندگان و بهره برداران آن عرصه است) است که به ما امکان تولید و مصرف RESTful API  های queryable   و ineroperable رو به روشی ساده و استاندارد میده.به طور مثال مواردی رو مانند اینکه کدام متد های HTTP باید برای چه نوع درخواست هایی استفاده بشن، چه Status Code ی رو باید برگردونده بشه و مواردی مثل قرارداد های URL.OData  علاوه بر این که  میتونه شامل کوئری ها، فیلتر ها و صفحه بندی باشه، همچنین میتونه توابع و متدهای سفارشی شده دیگه ای رو هم فراخوانی کنه.

Option Query ها 

در زیر نمونه هایی از Query Option  هایی که ASP.NET Core WebAPI  از اون ها پشتیبانی میکنه رو مرور می کنیم:

  • $orderby : داده های دریافتی را می تونه در قالب های خاصی به طور مثال صعودی و یا نزولی مرتب کنه.
  • $select : می تونه ستون ها و یا پراپرتی هایی از مجموعه نتایج، انتخاب کنه. مشخص می کنه که همه ی اتریبیوت ها و پراپرتی ها در نتیجه دریافت شده درج بشن.
  • $skip : برای ردشدن و نادیده گرفتن بخشی از داده های دریافتی. به طور مثال من میخوام از 100 رکورد اولی که از دیتابیس واکشی کردم، صرف نظر کنم و داده های بعد از اون رو به نمایش بذارم.
  • $top : فقط به تعداد عددی که در مقابل top قرار میگیره، رکورد ها رو واکشی می کنه. به طور مثال من نیاز دارم فقط تعداد 10 رکورد اول رو فراخونی کنم.
  • $filter :نتیجه تعیین شده رو بر اساس شرایط خاصی تعیین می کنه، مثل بخشی از LINQ ها. به طور مثال من میخوام دانش آموزانی رو واکشی کنم که معدل اون ها بالای 18 هست و دارای جنسیت مونث هستن، می تونم از این query option  استفاده کنم 
  • $inlinecount : از این ویژگی برای صفحه بندی در سمت کلاینت استفاده میشه، تعداد کل موجودیت های واکشی شده از سمت سرور را مشخص میکنه.

نیارمندی های استفاده از ODAta 

  • Visual Studio 2019 
  • SDK.Net5.0

مراحل پیاده سازی ODAta  در ASP.NET Core 5

قبل از هر چیزی به نرم افزار Visual Studio 2019 نیاز داریم که بتونیم یک پروژه از نوع ASP.NET Core 5.0 Web Api   ایجاد کنیم.
ایجاد پروژه و استفاده از OData  

  • در ابتدا گزینه Create a new project  را انتخاب و از لیست گزینه های موجود،  ASP.NET Core Web API را انتخاب می کنم.
  • در صفحه بعدی اطمینان حاصل می کنم که مقدار قرار داده شده در کادر Target framework برابر با.NET5
  • در مرحله بعد گزینه Empty رو انتخاب می کنم تا پروژه مورد نظرم ایجاد بشه.

نصب پکیج های مورد نیاز از Nuget Package Manager :

  • Microsoft.AspNetCore.OData
  • Microsoft.AspNetCore.Mvc.NewtonsoftJson

یا می تونم در پنجره Package Manager Console  اون ها رو به صورت کامند نصب کنم :

Install-Package Microsoft.AspNetCore.OData

Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson
  • در مسیر اصلی پروژه،  پوشه ای تحت عنوان Model ایجاد و درون اون کلاسی با عنوان Employee  قرار دادم.
public class Employee 
    {  
        public int   Id { get; set; }  
        public string Name { get; set; }  
        public string Role { get; set; }  
        public string City { get; set; }  
        public int  Pincode { get; set; }  
    }  
  •  تو این مرحله،  نوبت ساخت business logic  پروژس. می تونم این کار رو در یک پروژه جداگانه درون solution انجام بدم و یا در مسیر اصلی پروژه اون رو ایجاد کنم که بسته به معماری هست که در ساخت پروژه ازش استفاده می کنم.  تو این پروژه چون به صورت نمونه هست من در روت اصلی پروژه پوشه ای به نام Services ایجاد کردم و داخل اون کلاسی تحت عنوان EmployeeService ساختم تا سرویس هام رو درون اون قرار بدم.
  •  تو این پروژه چون من با دیتابیسی کار نمی کنم، داده ها رو به صورت استاتیک ایجاد می کنم تا در حقیقت یک شبیه سازی از یک پروژه واقعی باشه. داخل کلاس EmployeeService متد زیر رو قرار دادم.
public class EmployeeService  
    {  
        public List<EmployeeModel> CreateData()  
        {  
            List<EmployeeModel> employeeModels = new(); // C# 9 Syntax  
  
            employeeModels.Add(new EmployeeModel { Id = 1, Name = "Jay", Role = "Developer", City = "Hyderabad", Pincode = 500072 });  
            employeeModels.Add(new EmployeeModel { Id = 2, Name = "Chaitanya ", Role = "Developer", City = "Bangalore", Pincode = 500073 });  
            employeeModels.Add(new EmployeeModel { Id = 3, Name = "Bobby Kalyan", Role = "Developer", City = "Chennai", Pincode = 500074 });  
            employeeModels.Add(new EmployeeModel { Id = 4, Name = "Praveen", Role = "Developer", City = "Vizag", Pincode = 500075 });  
            employeeModels.Add(new EmployeeModel { Id = 5, Name = "Naidu", Role = "Developer", City = "Cochin", Pincode = 500076 });  
            employeeModels.Add(new EmployeeModel { Id = 6, Name = "Yateesh", Role = "Developer", City = "Tirupati", Pincode = 500077 });  
            employeeModels.Add(new EmployeeModel { Id = 7, Name = "Priyanka", Role = "Developer", City = "Khammam", Pincode = 500064 });  
            employeeModels.Add(new EmployeeModel { Id = 8, Name = "Jisha", Role = "QA", City = "Kurnool", Pincode = 500078 });  
            employeeModels.Add(new EmployeeModel { Id = 9, Name = "Aravind", Role = "QA", City = "Anakapalli", Pincode = 500214 });  
            employeeModels.Add(new EmployeeModel { Id = 10, Name = "Manikanta", Role = "QA", City = "Tuni", Pincode = 500443 });  
            employeeModels.Add(new EmployeeModel { Id = 11, Name = "Chinna", Role = "QA", City = "Srikakulam", Pincode = 500534 });  
            employeeModels.Add(new EmployeeModel { Id = 12, Name = "Samuel", Role = "QA", City = "Bhimavaram", Pincode = 500654 });  
            employeeModels.Add(new EmployeeModel { Id = 13, Name = "John", Role = "QA", City = "Kharagpur", Pincode = 5000765 });  
            employeeModels.Add(new EmployeeModel { Id = 14, Name = "Edward", Role = "QA", City = "Mumbai", Pincode = 5000224 });  
            employeeModels.Add(new EmployeeModel { Id = 15, Name = "Nihaan", Role = "QA", City = "Mangalore", Pincode = 500965 });  
            return employeeModels;  
        }  
  
        public List<EmployeeModel> GetEmployees() => CreateData().ToList();  
    }   
  • تو این مرحله باید سرویسم رو به صورت Dependency Injection درون فایل startup.cs کانفیگ کنم.بنابراین دستورات زیر رو به متد ConfigureService اضافه می کنم.
services.AddControllers().AddNewtonsoftJson();  
 services.AddScoped<EmployeeService>();  
 services.AddOData();
  • دارم کم کم به مراحل جذابش نزدیک میشم 😊. 
  • OData از قابلیت های مختلفی برای مسیریابی استفاده میکنه. مثلا میتونیم تمام اون query option هایی که بالا توضیح دادم و به پروژه اضافه کنیم. پس من کد های زیر رو به عنوان middleware به endpoint هام اضافه می کنم.
app.UseEndpoints(endpoints =>  
            {  
                endpoints.EnableDependencyInjection();  
                endpoints.Select().Count().Filter().OrderBy().MaxTop(100).SkipToken().Expand();  
                endpoints.MapControllers();  
                  
            });  
  • حالا وقت اون رسیده که کنترلر خودمو ایجاد بکنم، پس یه کنترلر به نام Employee ایجاد میکنم و داخلش  یه متد به اسم GetData مینویسم که مسئول واکشی داده ها از لیستیه که بالاتر به صورت استاتیک تعریف کردم.
//[Route("api/[controller]")]  
    [ApiController]  
    public class EmployeeController : ControllerBase  
    {  
        private readonly EmployeeService _employeeService;  
  
        public EmployeeController(EmployeeService employeeService)  
        {  
            _employeeService = employeeService;  
        }  
  
        [HttpGet(nameof(GetData))]  
        [EnableQuery]  
        public IActionResult GetData() => Ok(_employeeService.GetEmployees());  
    } 

 دقت کنین که در ابتدا سرویس خودم رو در سازنده کلاس نمونه سازی کردم و بعد در متد GetData خودم ازش استفاده کردم. 

  • از اتریبیوت EnableQueryدر بالای متد GetData استفاده کردم تا بتونم با query option های مد نظرم در هنگام فراخوانی این متد، کار کنم.
  • تا ایجا پروژه من تکمیل شده و من نیاز دارم که اون رو تست کنم. برای تست API هام از برنامه Postman استفاده می کنم.
  • $select : درون Postman یه درخواست از نوع Get ایجاد می کنم با این آدرس :

https://localhost:44356/GetData?$select=id,name
با ارسال درخواست بالا،  خروجی مورد نظر به شکل زیر میشه :

[
     {
                 “Id” : “1”,
                 “Name” : “Jay”,
     },
     {
                 “Id” : “2”,
                 “Name” : “Chaitanya”,
     },
     {
                 “Id” : “3”,
                 “Name” : “Bobby kalyan”,
     },
]
  • $skip : درون Postman یه درخواست دیگه از نوع Get ایجاد می کنم با این آدرس :

https://localhost:44356/GetData?$select=id,name&skip=2
با ارسال درخواست بالا،  خروجی مورد نظر به شکل زیر میشه :

[
     {
                 “Id” : “3”,
                 “Name” : “Bobby Kalyan”,
     },
     {
                 “Id” : “4”,
                 “Name” : “Praveen”,
     },
     {
                 “Id” : “5”,
                 “Name” : “Naidu”,
     },
…
]
  • $top : درون Postman یه درخواست دیگه از نوع Get ایجاد می کنم با این آدرس :

https://localhost:44356/GetData?$select=id,name&top=2
با ارسال درخواست بالا،  خروجی مورد نظر به شکل زیر میشه :

[
     {
                 “Id” : “1”,
                 “Name” : “Jay”,
     },
     {
                 “Id” : “2”,
                 “Name” : “Chaitanya”,
     }
]

در مقاله بعدی در مورد query option  filter صحبت می کنم