مشکل در خودکار کردن تعاریف DbSet ها در EF Code first
هدر دو تکه
- هر سطر یا هر سلول یک جدول میتواند حاوی یک جدول جدید باشد.
- از نحوهی تشکیل topTable و infoTable مطلب «تهیهی کارت با فرمت PDF با استفاده از کتابخانه iTextSharp» ایده بگیرید.
- روشهای دیگری هم برای تشکیل هدر وجود دارند؛ برای مثال استفاده از html.
عدم نمایش متن در هدر سفارشی
آیا از زمان حضور در محل کار، جهت یادگیری استفاده می کنید؟
ارتباطات بلادرنگ و SignalR
در اینجا کلمه بلادرنگ به معنای ارسال اطلاعات از طرف سرور به کلاینتها با فاصله زمانی بسیار کوتاهی از به روز رسانی اطلاعات صورت گرفته در سمت سرور است.
نمونهای از این برنامهها شامل موارد ذیل هستند:
- اطلاع رسانی همزمان به گروهی از کاربران
- جستجوهای زنده و به روز رسانیهایی از این دست
- نمایش بلادرنگ قیمتها و وضعیت تجاری محصولات و سهامها
- بازیهای تعاملی
- برنامههای گروهی و تعاملی (مانند برنامههای Chat)
- برنامههای شبکههای اجتماعی (برای مثال پیام جدیدی دارید؛ شخص خاصی آنلاین یا آفلاین شد و امثال آن)
بنابراین به صورت خلاصه قصد داریم به ارائه بازخوردها و اطلاع رسانیهای بلادرنگ یا نسبتا سریع و به روز از سمت سرور به کلاینتها برسیم.
برای مثال یک دیتاگرید را درنظر بگیرید. دو کاربر در شبکه صفحه یکسانی را گشودهاند و یکی از آنها مشغول به ویرایش و یا حذف اطلاعات است. در ارتباطات بلادرنگ کاربر یا کاربران دیگر نیز باید (یا بهتر است) در زمانیکه گرید یکسانی را گشودهاند، بلافاصله آخرین تغییرات را ملاحظه کنند. یا حتی حالتی را درنظر بگیرید که شخصی SQL Server management studio را گشوده و در آنجا مشغول به تغییر اطلاعات گردیده است. در این حالت نیز بهتر است آخرین تغییرات بلافاصله به اطلاع کاربران رسانده شوند.
معرفی الگوی Push service
البته باید دقت داشت که الگوی push service یک الگوی رسمی ذکر شده در گروههای مرسوم الگوهای طراحی نیست، اما مفهوم آن سرویسی است که چندین کار ذیل را انجام میدهد:
الف) پذیرش اتصالات از چندین مصرف کننده. مصرف کنندهها در اینجا الزاما محدود به کلاینتهای وب یا دسکتاپ نیستند؛ میتوانند حتی یک سرور یا سرویس دیگر نیز باشند.
ب) قادر است اطلاعات را به مصرف کنندههای خود ارسال کند. این سرویس میتواند یک برنامه ASP.NET باشد یا حتی یک سرویس متداول ویندوز.
ج) در اینجا چندین منبع خارجی مانند یک بانک اطلاعاتی یا تغییرات رخ داده توسط یک سخت افزار که میتوانند سبب بروز رخدادهایی در push service گردند نیز میتواند وجود داشته باشند. هر زمان که تغییری در این منابع خارجی رخ دهد، مایل هستیم تا مصرف کنندهها را مطلع سازیم.
پروتکل HTTP و ارتباطات بلادرنگ
پروتکلی که در ارتباطات بلادرنگ مبتنی بر SignalR مورد استفاده قرار میگیرد، HTTP است و از قابلیتهای Request و Response آن در اینجا بیشترین بهره برده میشود. پیاده سازی Push عموما بر مبنای یکی از روشهای متداول زیر است:
1) Periodic polling
به این معنا که مثلا هر 10 ثانیه یکبار، کاری را انجام بده؛ مانند ارسال متناوب: آیا تغییری رخ داده؟ آیا تغییری رخ داده؟ و .... به همین ترتیب. این روش اصلا بهینه نبوده و منابع زیادی را خصوصا در سمت سرور مصرف خواهد کرد. برای مثال:
function getInfo() { $.ajax("url", function ( newInfo){ if ( newInfo != null) { // do something with the data } }); // poll again after 20 seconds setTimeout(getInfo,20000); } // start the polling loop getInfo();
2) Long polling
به آن HTTP Streaming یا Comet هم گفته میشود. این روش نسبتا هوشمند بوده و کلاینت اتصالی را به سرور برقرار خواهد کرد. سرور در این حالت تا زمانیکه اطلاعاتی را در دسترس نداشته باشد، پاسخی نخواهد داد. برای نمونه:
function getNewInfo(){ $.ajax("url", function (newinfo) { // do something with the data // start the new request getNewINfo(); }); } // start the polling loop getNewInfo();
این روش نسبت به حالت Periodic polling بهینهتر است اما نیاز به اتصالات زیادی داشته و همچنین تردهای بسیاری را در سمت سرور به خود مشغول خواهد کرد.
3) Forever frame
فقط در IE پشتیبانی میشود. در این روش یک Iframe مخفی توسط مرورگر تشکیل شده و از طریق آن درخواستی به سرور ارسال میشود. سپس سرور متناوبا با تزریق اسکریپتهایی به این Iframe سبب فراخوانی مجدد وضعیت خود میگردد. در این روش نیز به ازای هر درخواست و پاسخ، ارتباطات گشوده و بسته خواهند شد.
4) Server Sent Events یا SSE
این مورد جزو استاندارد HTML5 است. در اینجا اتصالی برقرار شده و دادهها از طریق اتصالات HTTP منتقل میشوند.
var eventSrc = new EventSource("url"); // register event handler for the message eventSrc.addEventListener( "message",function (evt) { //process the data });
تنها تفاوت آن با حالت long polling در این است که پس از ارائه پاسخ به کلاینت، اتصال را قطع نمیکند. Long polling نیز اتصال را باز نگه میدارد، اما این اتصال را بلافاصله پس از ارائه پاسخ، میبندد.
5) Web sockets
Web sockets در سکوی کاری ویندوز، تنها در ویندوزهای 8، ویندوز سرور 2012 و دات نت 4 و نیم پشتیبانی میشود. هرچند این روش در حال حاضر به عنوان بهترین روش Push مطرح است اما به دلیل محدودیتی که یاد شد، مدتی طول خواهد کشید تا استفاده گستردهای پیدا کند.
var socket = new WebSocket("url"); socket.onmessage = function (msg) { var newInfo = msg.data; // do something with the data } // client can also send request to server socket.send(.... )
بلی. اگر به وضعیت فعلی سکوی کاری ASP.NET نگاه کنیم:
SignalR را میتوان مشاهده کرد که در گروه ساخت سرویسهای آن قرار گرفته است. همانطور که ملاحظه میکنید، این سرویس جدید آنچنان وابستگی به سایر اجزای آن نداشته و میتواند خارج از ASP.NET نیز مورد استفاده قرار گیرد.
SignalR چیست؟
SignalR راه حلی است سمت سرور برای نوشتن push services. همچنین به همراه کتابخانههای سمت کاربری است که ارتباطات push services را در انواع و اقسام سکوهای کاری میسر میسازد. SignalR سورس باز بوده و برای اعمال غیرهمزمان (asynchronous) بهینه سازی شده است.
SignalR بر اساس مدل ذهنی اتصالات ماندگار (persistent connections) طراحی شده است. اتصالات ماندگار را باید به عنوان اتصالاتی سریع و غیرطولانی درنظر گرفت. در اینجا Signal یک اتصال است که اطلاعاتی به آن ارسال میگردد و هدف، انتقال قطعات کوچکی از اطلاعات است و هدف، ارسال حجم عظیمی از اطلاعات نیست. برای مثال اطلاع رسانی سریعی صورت گیرد که تغییراتی رخ داده است و سپس ادامه کار و دریافت اطلاعات واقعی توسط فرآیندهای متداول مثلا HTTP GET انجام شود. البته باید دقت داشت SignalR نیز نهایتا از یکی از 5 روش push بررسی شده در این قسمت استفاده میکند. اما بر اساس تواناییهای کلاینت و سرور، به صورت هوشمند بهترین و بهینهترین انتخاب را به کاربر ارائه میدهد.
اتصالات ماندگار قسمت سطح پایین SignalR را تشکیل میدهند. سطح بالاتر آن که این مفاهیم را به شکلی کپسوله شده ارائه میدهد، Hubs نام دارد که پایه اصلی دوره جاری را تشکیل خواهد داد.
همانطور که عنوان شد، SignalR سورس باز بوده و دارای مخزن کدی عمومی در GitHub است. همچنین بستههای تشکیل دهندهی آن از طریق NuGet نیز قابل دریافت هستند. این بستهها شامل هسته SignalR و کلاینتهای آن مانند کلاینتهای WinRT، سیلورلایت، jQuery، ویندوز فون8 و امثال آن هستند.
شروع کار با SignalR
تیم SignalR مثالی مقدماتی از نحوه کار با SignalR را به صورت یک بسته NuGet ارائه دادهاند که از طریق آدرس و فرمان ذیل قابل دریافت است:
PM> Install-Package Microsoft.AspNet.SignalR.Sample
پس از دریافت مثال، یکبار پروژه را کامپایل کرده و سپس بر روی فایل StockTicker.html آن کلیک راست نموده و گزینه مشاهده در مرورگر را انتخاب کنید. همچنین برای اینکه این مثال را بهتر مشاهده کنید، بهتر است دو وهله از مرورگر را باز کرده و آدرس باز شده را در آن بررسی کنید تا اعمال تغییرات همزمان به کلاینتهای متفاوت را بهتر بتوان بررسی و مشاهده کرد.
در طراحی مدل دامین، بیشتر مواقع از نوعهای اولیه مانند int , string,… استفاده میکنیم و به عبارتی میتوانیم بگوییم در استفاده از این نوع داده وسواس داریم. قطعه کد زیر را در نظر بگیرید:
public class UserFactory { public User CreateUser(string email) { return new User(email); } }
اگر به خاطر داشته باشید، در قسمتهای قبلی در مورد مفهومی به نام Honesty صحبت کردیم. به طور ساده باید بتوانیم از روی امضای تابع، کاری را که تابع انجام میدهد و خروجی آن را ببینیم. این تابع Honest نیست؛ شرایطی که string میتواند درست نباشد، خالی باشد، طول غیر مجاز داشته باشد و ... را نمیتوانیم از امضای تابع حدس بزنیم.
جواب خیلی سادهاست؛ شما نیاز دارید تا یک Type اختصاصی را ایجاد کنید. برای مثال بجای استفاده از نوع string برای یک ایمیل، میتوانید یک کلاس را به عنوان Email ایجاد کنید که مشخصهای به نام Value دارد. این کار به روشهای مختلفی قابل انجام است؛ اما پیشنهاد من استفاده از این روش هست:
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; namespace ValueOf { public class ValueOf<TValue, TThis> where TThis : ValueOf<TValue, TThis>, new() { private static readonly Func<TThis> Factory; /// <summary> /// WARNING - THIS FEATURE IS EXPERIMENTAL. I may change it to do /// validation in a different way. /// Right now, override this method, and throw any exceptions you need to. /// Access this.Value to check the value /// </summary> protected virtual void Validate() { } static ValueOf() { ConstructorInfo ctor = typeof(TThis) .GetTypeInfo() .DeclaredConstructors .First(); var argsExp = new Expression[0]; NewExpression newExp = Expression.New(ctor, argsExp); LambdaExpression lambda = Expression.Lambda(typeof(Func<TThis>), newExp); Factory = (Func<TThis>)lambda.Compile(); } public TValue Value { get; protected set; } public static TThis From(TValue item) { TThis x = Factory(); x.Value = item; x.Validate(); return x; } protected virtual bool Equals(ValueOf<TValue, TThis> other) { return EqualityComparer<TValue>.Default.Equals(Value, other.Value); } public override bool Equals(object obj) { if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; return obj.GetType() == GetType() && Equals((ValueOf<TValue, TThis>)obj); } public override int GetHashCode() { return EqualityComparer<TValue>.Default.GetHashCode(Value); } public static bool operator ==(ValueOf<TValue, TThis> a, ValueOf<TValue, TThis> b) { if (a is null && b is null) return true; if (a is null || b is null) return false; return a.Equals(b); } public static bool operator !=(ValueOf<TValue, TThis> a, ValueOf<TValue, TThis> b) { return !(a == b); } public override string ToString() { return Value.ToString(); } } }
public class EmailAddress : ValueOf<string, EmailAddress> { }
EmailAddress emailAddress = EmailAddress.From("foo@bar.com");
public class Address : ValueOf<(string firstLine, string secondLine, Postcode postcode), Address> { }
روش معرفی شدهی در این مقاله، صرفا جهت آشنایی بیشتر شما و داشتن کدی تمیزتر از طریق مفاهیم برنامه نویسی تابعی خواهد بود. در دنیای واقعی، احتمالا مسائلی را برای ذخیره سازی این آبجکتها و یا کار با کتابخانههایی مانند Entity Framework خواهید داشت که به سادگی قابل حل است.
در صورتیکه مشکلی در پیاده سازی داشتید، میتوانید مشکل خود را زیر همین مطلب و یا بر روی gist آن کامنت کنید.
در مطلب پیشنیاز فوق، تنظیمات روابط ارث بری را تا EF 6.x، میتوانید مطالعه کنید. در EF Core 1.0 RTM، فقط رابطهی TPH که در آن تمام کلاسهای سلسه مراتب ارث بری، به یک جدول در بانک اطلاعاتی نگاشت میشوند، پشتیبانی میشود. سایر روشهای ارث بری که در EF 6.x وجود دارند، مانند TPT و TPC، قرار است به نگارشهای پس از 1.0 RTM آن اضافه شوند:
- لیست مواردی که قرار است به نگارشهای بعدی اضافه شوند
- پیگیری وضعیت پیاده سازی TPT
- پیگیری وضعیت پیاده سازی TPC
طراحی یک کلاس پایه، بدون تنظیمات ارث بری روابط
مرسوم است که یک کلاس ویژه را به نام BaseEntity، به شکل زیر تعریف کنند؛ که اهدف آن حداقل سه مورد ذیل است:
الف) کاهش ذکر فیلدهای تکراری در سایر کلاسهای دومین برنامه، مانند فیلد Id
ب) نشانه گذاری موجودیتهای برنامه، جهت یافتن سریع آنها توسط Reflection (برای مثال افزودن خودکار موجودیتها به Context برنامه با یافتن تمام کلاسهایی که از نوع BaseEntity هستند)
ج) مقدار دهی خودکار یک سری از فیلدهای ویژه، مانند زمان افزوده شدن رکورد و آخرین زمان ویرایش شدن رکورد و امثال آن
public class BaseEntity { public int Id { set; get; } public DateTime? DateAdded { set; get; } public DateTime? DateUpdated { set; get; } }
public class Person : BaseEntity { public string FirstName { get; set; } public string LastName { get; set; } }
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Ignore<BaseEntity>();
مشکل! اگر بر روی کلاس پایهی تعریف شده تنظیماتی را اعمال کنید (هر نوع تنظیمی را)، با توجه به فراخوانی متد Ignore، این تنظیمات نیز ندید گرفته خواهند شد.
اگر علاقمند بودید تا این تنظیمات را به تمام کلاسهای مشتق شدهی از BaseEntity به صورت خودکار اعمال کنید، روش کار به صورت ذیل است:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Ignore<BaseEntity>(); foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { var dateAddedProperty = entityType.FindProperty("DateAdded"); dateAddedProperty.ValueGenerated = ValueGenerated.OnAdd; dateAddedProperty.SqlServer().DefaultValueSql = "getdate()"; var dateUpdatedProperty = entityType.FindProperty("DateUpdated"); dateUpdatedProperty.ValueGenerated = ValueGenerated.OnAddOrUpdate; dateUpdatedProperty.SqlServer().ComputedColumnSql = "getdate()"; }
خلاصهی آن نیز به این صورت است:
الف) نیازی نیست تا در حین ثبت اطلاعات موجودیتهای خود، فیلدهای DateAdded و یا DateUpdated را مقدار دهی کنید.
ب) فیلد DateAdded فقط در زمان اولین بار ثبت در بانک اطلاعاتی، به صورت خودکار توسط متد getdate مقدار دهی میشود.
ج) فیلد DateUpdated در هر بار فراخوانی متد SaveChanges (یعنی در هر دو حالت ثبت و یا به روز رسانی) به صورت خودکار توسط متد getdate مقدار دهی میشود.
تذکر! بدیهی است متد getdate، یک متد بومی سمت SQL Server است و این روش خاص تعیین مقدار پیش فرض فیلدها، فقط با SQL Server کار میکند. همچنین این getdate، به معنای دریافت تاریخ و ساعت سروری است که SQL Server بر روی آن نصب شدهاست و نه سروری که برنامهی وب شما در آن قرار دارد و برنامه کوچکترین دخالتی را در مقدار دهی این مقادیر نخواهد داشت.
در قسمتهای بعدی که مباحث Tracking را بررسی خواهیم کرد، روش دیگری را برای طراحی کلاسهای پایه و مقدار دهی خواص ویژهی آنها مطرح میکنیم که مستقل است از نوع بانک اطلاعاتی مورد استفاده.
بررسی تنظیمات رابطهی Table per Hierarchy یا TPH
رابطهی TPH یا تشکیل یک جدول بانک اطلاعاتی، به ازای تمام کلاسهای دخیل در سلسه مراتب ارث بری تعریف شده، بسیار شبیه است به حالت BaseEntity فوق که در آن نیز ارث بری تعریف شده، در نهایت منجر به تشکیل یک جدول، در سمت بانک اطلاعاتی میگردد. با این تفاوت که در حالت TPH، فیلد جدیدی نیز به نام Discriminator، به تعریف نهایی جدول ایجاد شده، اضافه میشود. از فیلد Discriminator جهت درج نام کلاسهای متناظر با هر رکورد، استفاده شده است. به این ترتیب EF در حین کار با اشیاء، دقیقا میداند که چگونه باید خواص متناظر با کلاسهای مختلف را مقدار دهی کند و نوع ردیف درج شدهی در بانک اطلاعاتی چیست؟
باید دقت داشت که تنظیمات TPH، شیوه برخورد پیش فرض EF Core با ارث بری کلاسها است و نیاز به هیچگونه تنظیم اضافهتری را ندارد. اما اگر علاقمند بودید تا نام فیلد خودکار Discriminator و مقادیری را که در آن درج میشوند، سفارشی سازی کنید، روش کار صرفا توسط Fluent API میسر است و به صورت زیر میباشد:
public class Blog { public int BlogId { get; set; } public string Url { get; set; } } public class RssBlog : Blog { public string RssUrl { get; set; } } class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .HasDiscriminator<string>("blog_type") .HasValue<Blog>("blog_base") .HasValue<RssBlog>("blog_rss"); } }
اگر این تنظیمات سفارشی صورت نگیرند، از نامهای پیش فرض نوعها برای مقدار دهی ستون Discriminator، مانند تصویر ذیل استفاده خواهد شد:
برای کوئری نوشتن در این حالت میتوان از متد الحاقی OfType جهت فیلتر کردن اطلاعات بر اساس کلاسی خاص، کمک گرفت:
var blog1 = db.Blogs.OfType<RssBlog>().FirstOrDefault(x => x.RssUrl == "………");
با آمدن Asp.Net Web API کار ساختن Web APIها برای برنامه نویسها به خصوص دسته ای که با ساخت API و
وب سرویس آشنا نبودند خیلی سادهتر شد . اگر با Asp.Net MVC آشنا باشید
خیلی سریع میتوانید اولین Web Service خودتان را بسازید .
در صفحه مربوط به Asp.Net Web API آمده است که این فریمورک بستر مناسبی برای ساخت و توسعه برنامه های RESTful است . اما تنها ساختن کنترلر و اکشن و برگشت دادن دادهها به سمت کلاینت ، به خودی خود برنامه شما رو تبدیل به یک RESTful API نمیکند .
مثل تمام مفاهیم و ابزارها ، طراحی و ساختن RESTful API هم دارای اصول و Best Practice هایی است که رعایت آنها به خصوص در این زمینه از اهمیت زیادی برخوردار است . همانطور که از تعریف API برمی آید شما در حال طراحی رابطی هستید تا به توسعه دهندگان دیگر امکان دهید از دادهها و یا خدمات شما در برنامهها و سرویس هایشان استفاده کنند . مانند APIهای توئیتر و نقشه گوگل که برنامههای زیادی بر مبنای آنها ساخته شده اند . در واقع توسعه دهندگان مشتریان API شما هستند .
بهره وری توسعه دهنده مهمترین اصل
اینطور میتوان نتیجه گرفت که اولین و
مهمترین اصل در طراحی API باید رضایت و موفقیت توسعه دهنده در درک و
یادگیری سریع API شما ،نه تنها با کمترین زحمت بلکه همراه با حس نشاط ، باشد. ( تجربه کاربری در اینجا هم میتواند صدق کند ). سعی کنید در زمان
انتخاب از بین روشهای طراحی موجود ، از دیدگاه توسعه دهنده به مسئله نگاه کنید .
خود را به جای او قرار دهید و تصور کنید که میخواهید با استفاده از API
موجود یک رابط کاربری طراحی کنید یا یک اپلیکشن برای موبایل بنویسید و اصل را این
نکته قرار دهید که بهره وری برنامه نویس را حداکثر کنید. ممکن است گاهی بین طرحی که بر اساس این اصل برای API خود در نظر داریم و یکی از اصول یا استانداردها تعارض بوجود بیاید . در این موارد بعد از اینکه مطمئن شدیم این اختلاف ناشی از طراحی و درک اشتباه خودمان نیست (که اکثرا هست ) ارجحیت را باید به طراحی بدهیم .
تهیه مستندات API
اگر برای پروژه وب سایتتان هیچ نوشته ای یا توضیحی ندارید ، جالب نیست اما خودتان ساختار برنامه خود را میشناسید و کار را پیش میبرید. اما توسعه دهنده ای که از API شما میخواهد استفاده کند و به احتمال زیاد شما را نمیشناسد ، عضو تیم شما هم نیست ، هیچ ایده ای درباره ساختار آن ، روش نامگذاری توابع و منابع، ساختار Urlها ، چگونگی و گامهای پروسه درخواست تا دریافت پاسخ ندارد ،و به مستندات شما وابسته است و تمام اینها باید در مستندات شما باشد. بیشتر توسعه دهندهها قبل از تست کردن API شما سری به مستندات میزنند ، دنبال نمونه کد آموزشی میگردند و در اینترنت درباره آن جستجو میکنند . ازینرو مستندات ( کارامد ) یک ضرورت است :
1- در مستندات باید هم درباره کلیت و هم در مورد تک تک توابع ( پارامترهای معتبر ، ساختار پاسخها و ... ) توضیحات وجود داشته باشد.
2- باید شامل مثالهایی از سیکل کامل درخواستها / پاسخها باشند .
3- تغییرات اعمال شده نسبت به نسخههای قبلی باید در مستندات بیان شوند .
4- (در وب ) یافتن و جستجو کردن در مستنداتی که به صورت فایل Pdf هستند یا برای دسترسی نیاز به Login داشته باشند سخت و آزاردهنده هستند.
5- کسی را داشته باشید تا با و بدون مستندات با API شما کار کند و از این روش برای تکمیل و اصلاح مستندات استفاده کنید.
رعایت نسخه بندی و حفظ نسخههای قبلی به صورت فعال برای مدت معین
یک API تقریبا هیچوقت کاملا پایدار نمیشود و اعمال تغییرات برای بهبود آن اجتناب ناپذیر هستند . مسئله مهم این است که چطور این تغییرات مدیریت شوند . مستند کردن تغییرات ، اعلام به موقع آنها و دادن یک بازه زمانی کافی برای ارتقا یافتن برنامه هایی که از نسخههای قدیمیتر استفاده میکنند نکات مهمی هستند . همیشه در کنار نسخه بروز و اصلی یک یا دو نسخه ( بسته به API و کلاینتهای آن ) قدیمیتر را برای زمان مشخصی در حالت سرویس دهی داشته باشید .
داشتن یک روش مناسب برای اعلام تغییرات و ارائه مستندات و البته دریافت بازخورد از استفاده کنندگان
تعامل با کاربران برنامه باید از کانالهای مختلف وجود داشته باشد .از وبلاگ ، Mailing List ، Google Groups و دیگر ابزارهایی که در اینترنت وجود دارند برای انتشار مستندات ، اعلام بروزرسانیها ، قرار دادن مقالات و نمونه کدهای آموزشی ، پرسش و پاسخ با کاربران استفاده کنید .
مدیریت خطاها به شکل صحیح که به توسعه دهنده در آزمودن برنامه اش کمک کند.
از منظر برنامه نویسی که از API شما استفاده میکند هرآنچه در آنسوی API اتفاق میافتد یک جعبه سیاه است . به همین جهت خطاهای API شما ابزار کلیدی برای او هستند که خطایابی و اصلاح برنامه در حال توسعه اش را ممکن میکنند . علاوه بر این ، زمانی که برنامه نوشته شده با API شما مورد استفاده کاربر نهایی قرار گرفت ، خطاهای به دقت طراحی شده API شما کمک بزرگی برای توسعه دهنده در عیب یابی هستند .
1- از Status Code های HTTP استفاده کنید و سعی کنید تا حد ممکن آنها را نزدیک به مفهوم استانداردشان بکار ببرید .
2- خطا و علت آن را به زبان روشن توضیح دهید و در توضیح خساست به خرج ندهید .
3- در صورت امکان لینکی به یک صفحه وب که حاوی توضیحات بیشتری است را در خطا بگنجانید .
رعایت ثبات و یکدستی در تمام بخشهای طراحی که توانایی پیش بینی توسعه دهنده را در استفاده از API افزایش میدهد .
داشتن مستندات لازم است اما این بدین معنی نیست که خود API نباید خوانا و قابل پیش بینی باشد . از هر روش و تکنیکی که استفاده میکنید آن را در تمام پروژه حفظ کنید . نامگذاری توابع/منابع ، ساختار پاسخها ، Urlها ، نقش و عملیاتی که HTTP methodها در API شما انجام میدهند باید ثبات داشته باشند . از این طریق توسعه دهنده لازم نیست برای هر بخشی از API شما به سراغ فایلها راهنما برود . و به سرعت کار خود را به پیش میبرد .
انعطاف پذیر بودن API
API توسط کلاینتهای مختلفی و برای افراد مختلفی مورد استفاده قرار میگیرد که لزوما همهی آنها ساختار یکسانی ندارند و API شما باید تا جای ممکن بتواند همه آنها را پوشش دهد . محدود بودن فرمت پاسخ ، ثابت بودن فیلدهای ارسالی به کلاینت ، ندادن امکان صفحه بندی ، مرتب سازی و جستجو در دادهها به کلاینت ، داشتن تنها یک نوع احراز هویت ، وابسته بودن به کوکی و ... از مشخصات یک API منجمد و انعطاف ناپذیر هستند .
اینها اصولی کلی بودند که بسیاری از آنها مختص طراحی API نیستند و در تمام حوزهها قابل استفاده بوده ، جز الزامات هستند . در قسمتهای بعدی نکات اختصاصیتری را بررسی خواهیم کرد .