چگونه یک خروجی استاندارد از api داشته باشیم

امروزه با رشد اپلیکیشن های همرا و وب اپلیکیشن تک صفحه ای وب نوشتن وب سرویس کار مرسومی شده و روز به روز در حال روشد میباشد.مزایا وب سرویس :جدا سازی back end و front end : کسی که سرور کار میکنه دیگه درگیر ui نمیشه چون ui وجود نداره و فقط خروجی json بازگشت خواهد داد.سرعت بسیار بالا : در صفحات عادی وقتی ادرس سایتی را وارد میکنید کل صفحه همراه با دادها اعم از عکس نوشته و ... لود میشوند ولی در وب سرویس فقط یک رشته از جیسون داده ها برگشت داده میشود.؛ cross platform : وابستگی به سیستم عامل یا پلتفرم خاصی ندارد؛ cross platform به زبان ساده وابستگی به سیستم خاصی ندارد و رو همه سیستم ها اجرا میشودبه عبارت دیگر مستقل از سیستم عامل است تا اینجای کار با وب سرویس ها اشنا شدیم.با ذکر یک مثال مقاله را شروع میکنیمبر رویه وب سرویس زیر کلیک کنیدwww.doman.com/api/todos/1اگر بدون هیچ مشکلی فراخوانی شده باشد خرجی ان به یک مقدار جیسونی به شکل زیر است{ &quotuserId&quot: 1, &quotid&quot: 1, &quottitle&quot: &quotdelectus aut autem&quot, &quotcompleted&quot: false }این سبک خروجی ساده ترین حالت api response میباشد که داده به صورت جیسونی از شی برگشت داده میشود.مجددا وب سرویس بالا رو با کد 0 فراخونی کنید www.doman.com/api/todos/0این بار طبق داده ارسالی که مشاهده میکنیم باید خروجی NotFound نمایش داده شود ولی خروجی به شکل زیر است{}نوع خروجی های بالا بدون مشکل و درست میباشند ولی اجازه بدید با سایت های معروف دیگه مقایسه کنیم و تفاوت ان را ببینمسایت linkedin : وارد سایت لینکدین میشویم و با inspect گرفتن داده هایی که به صورت ajax فراخونی میشوند را مشاهده میکنیمresponse of linkedinهمانطور که در شکل بالا مشاهده میکنید داده ها در یک قالب مشخص شده بازگشت داده شده است.همچنین میتوانید وارد این سایت شوید و مجموعه ای از وب سرویس های استاندارد رو تست کنیدبه طور مثال رو لینک زیر کلیک کنیدwww.domain.com/api/users?page=2اگر به درستی فرخوانی کرده باشید خروجی به شکل زیر خواهد بود{ &quotpage&quot: 2, &quotper_page&quot: 6, &quottotal&quot: 12, &quottotal_pages&quot: 2, &quotdata&quot: [ { &quotid&quot: 7, &quotemail&quot: &quotmichael.lawson@reqres.in&quot, &quotfirst_name&quot: &quotMichael&quot, &quotlast_name&quot: &quotLawson&quot, &quotavatar&quot: &quothttps://s3.amazonaws.com/uifaces/faces/twitter/follettkyle/128.jpg&quot } ] }در این مقاله قصد داریم نحوه پیاده یک خروجی استاندارد از وب سرویس هامون داشته باشیم.یک پرژه dotnet web api ایجاد کنید همچنین یک کنترلر با CRUD ایجاد کنید.به کد زیر دقت کنید.[HttpGet(&quotgetall&quot)] public ActionResult<List<Product>> getall() { var products = _ProductService.GetAllAsync(); return Ok(products); }کد بالا حالت پیشفرض میباشد اگر دقت کرده باشید با اینکه نوع خرجی اکشن ActionResult میباشد ولی هنگام برگشت Product بدون هیچ خطایی پروژه اجرا میشود در ادامه بیشتر این موضوع را برسی خواهیم کرد به زبان سادتر میتوان گفت که نو Product نمیتونه به ActionResult تبدیل بشه و منطقا باید خطا کامپایلر نمایش داده شود.پیاده سازی OperationResult در web api :خیلی وقت بود که دنبال پیاده سازی همچین پترنی بودم اکثر سایت ها به صورت خلاصه بیان کردن ولی با ادرس github یکی از بچه ها اشنا شدم و ایشون زحمت کشیدن به صورت کامل پیاده سازی رو انجام دادن .قبل از هر چیز وارد این لینک شوید و به صورت خلاصه مطالعه کنید.کاری که میخوایم انجام بدیم پیاده سازی یک قالب مدلی برای همه خروجی هامون است.به کد زیر دقت کنی.کد بالا یک struct تعریف کرده که یک نوع داده جنریکی از وردی میگرد همچنین داری چند پراپرتی وچند Static implicit operator است .دقت کنید در کدی که بالا برسی کردیم با وجود اینکه خروجی Action و مدل بازگشتی یکی نبود ولی باز خطایی گرفته دریافت نکردیم! چون عملیات Casting با implicit در پشت پرده هندل شده اند.توجه کنید implicit ها برای Cast کردن می باشند برای اطلاعات بیشتر میتوانید به این لینک مراجعه کنید برای شروع یک کلاس به نام ApiResult ایجاد کرده و به صورت زیر پیاده سازی کنیدpublic class ApiResult { public bool IsSuccess { get; set; } public ApiResultStatusCode StatusCode { get; set; } public string Message { get; set; } public ApiResult(bool isSuccess, ApiResultStatusCode statusCode, string message = null) { IsSuccess = isSuccess; StatusCode = statusCode; Message = message; } #region Implicit Operators public static implicit operator ApiResult(OkResult result) { return new ApiResult(true, ApiResultStatusCode.Success); } public static implicit operator ApiResult(NotFoundResult result) { return new ApiResult(false, ApiResultStatusCode.NotFound); } #endregion } public class ApiResult<TData> : ApiResult where TData : class { public TData Data { get; set; } public ApiResult(bool isSuccess, ApiResultStatusCode statusCode, TData data, string message = null) : base(isSuccess, statusCode, message) { Data = data; } #region Implicit Operators public static implicit operator ApiResult<TData>(TData data) { return new ApiResult<TData>(true, ApiResultStatusCode.Success, data); } public static implicit operator ApiResult<TData>(OkResult result) { return new ApiResult<TData>(true, ApiResultStatusCode.Success, null); } public static implicit operator ApiResult<TData>(NotFoundResult result) { return new ApiResult<TData>(false, ApiResultStatusCode.NotFound, null);} #endregion } public enum ApiResultStatusCode { Success = 0, ServerError = 1, NotFound = 2, در بالا یک کلاس جنیرک برای نوع داده های مختلف و یک کلاس برای اینکه اگر فقط از نوع داده ApiResult استفاده کنیم ایجاد کردیم. به قطعه کدی که در قسمت بالا اورده شده است دقت کنید.public static implicit operator ApiResult<TData>(OkResult result) { return new ApiResult<TData>(true, ApiResultStatusCode.Success, null); }کد بالا نمایانگر تبدیل خوتکار نوع داده ای OkResult به ApiResult<TData> میباشد.شما میتوانید هر نوع داده ای مختلف را به ApiResult<TData> تبدیل کنید برای مشاهده نمونه کامل کد را میتونید از این لینک مشاهده کنید .به کد زیر یک بار دیگر توجه کن[HttpGet(&quotgetall&quot)] public ActionResult<List<Product>> getall() { var products = _ProductService.GetAllAsync(); return Ok(products); }با استفاده از ActionResult و implicit ها با اینکه نوع خرجی تابع از نوع Product است ولی بدون خطا عمل Casting انجام میشود. شما متوانید Response Type های خود دانت نت مثل NotFound یا BadRequst را با implicitها پیاده سازی کنید.با این کار نوع خروجی خوانا و تمیزی خواهید داشت و کلاینت کارا با خوانایی و سرعت بیشتر میتوانند مدل های خود را bind کنند.اگه از مقاله راضی بودید میتونید از لینک زیر برام قهوه بخرید : ) https://www.coffeete.ir/sobhan