majid
majid
خواندن ۱۱ دقیقه·۹ ماه پیش

طراحی API

قواعد اصلی و کلی برای پیاده سازی اصولی یک API بصورت زیر است. هر کدام از این قواعد دارای جزییات و مفاهیم زیادی می‌باشد. در این قسمت صرفا اشاره‌ای به آنها کردم. برای ریز شدن در جزییات هرکدام باید جداگانه در موردشان بخوانید.

اشتباه نکنید، این قواعد ربطی به محدودیت های REST ندارد، صرفا قواعدی هستند که برای درست و کامل پیاده سازی کردن API لازم است.

۸ بخش اصلی در طراحی API

  • نام گذاری صحیح API
  • تعریف صحیح Endpoints و Routes
  • استفاده صحیح از Query Parameters
  • موارد پرتکرار در Request Header
  • مشخص کردن دیتاهای مورد نیاز در Request Body
  • موارد پرتکرار در Response Header
  • مشخص کردن دیتاهای مورد نیاز در Response Body
  • انتخاب درست Status Code برای انواع Responseها

۱. نام گذاری صحیح API

فرض کنید می‌خواهید ‌ api برای گرفتن اطلاعات یک کاربر بخصوص طراحی کنید، نباید نام api غیرشفاف باشد. " GetUsers " یک نامگذاری اشتباه برای این api خواهد بود. چون تصور می‌شه api با این نام اطلاعات تمام کاربران را به ما می‌دهد.

همچنین نباید از فعل استفاده کنیم. باید از اسمی استفاده کنیم که نماینده موجودیتی است که End point ما قصد انجام کوئری روی آن را دارد. دلیل این است که متد درخواست HTTP ما خود یک فعل دارد.
  • از یک نام واضح و مختصر استفاده کنید. اگر قصد دارید روی جدول کاربران کوئری بزنید، نباید نام api، مربوط به یک یا گروهی از کابران باشد. (Create Users/Delete User)

۲. تعریف صحیح Endpoints و Routes

یک endpoint جایی است که API درخواست‌ها را دریافت می کند. در واقع توابع یا resourceهایی هستند که از طریق API می‌توان به آنها دسترسی داشت.مانند حذف یک پست یا اطلاعات کتابخانه و یا یک کتاب خاص. endpoint عملکرد خاصی را انجام می دهند و تعدادی پارامتر را می‌گیرد و داده‌ها را باز می گرداند. برای اکثر سرویس‌ها، endpoint یک URL است.

یک route نامی است که برای دسترسی به endpoint استفاده می‌شه. یک route می‌تونه چند endpoint مرتبط داشته باشه و اینکه از کدوم آنها استفاده بشه به HTTP Verb بستگی داره.

برای مثال http://localhost:8000/users رو در نظر بگیرید.

در این مثال http://localhost:8000/users و http://localhost:8000/users/{userId} دو endpoint هستند و اینها route های زیر را دارند:

  • GET /users
  • GET /users/userId
  • PUT /users/userId
  • .......


۳. استفاده صحیح از Query Parameters:

پارامترهای پرس و جو رایج ترین نوع پارامترها هستند. آنها در انتهای URL درخواست پس از علامت سوال (؟)، با جفت های مختلف name=value که با علامت (&) از هم جدا شده اند ظاهر می شوند. پارامترهای پرس و جو می توانند مورد نیاز و اختیاری باشند. از این پارامتر بیشتر برای فیلترکردن دیتا و یا صفحه بندی استفاده می شود.

GET /users/findByStatus?status=available
GET /books?offset=100&limit=50

تعریف Header:

هدرهای API بخشی از request/response هستند که برای انتقال meta data در مورد request و response مورد نظر استفاده می‌شوند. به عبارت ساده تر، اینجا جایی است که می توانید اطلاعات اضافی در مورد request/response ارائه دهید. به عنوان مثال، مشخص میکنن که داده‌های ارسال شده در قالب JSON هستند، کدام نسخه از API را فراخوانی کند و .....

هدرها عموما بصورت جفت key:value هستند.

۴. موارد پرتکرار در Request Header:

User-Agent:

نرم افزار و نسخه client را شناسایی می کند.

Accept:

فرمت ترجیحی response را مشخص می کند و اطمینان می دهد که سرور response را در قالبی ارائه می دهد که کلاینت بتواند پردازش و درک کند. برای مثال "application/json" به سرور نشان می دهد که کلاینت response را در قالب JSON می‌پذیرد. چند نمونه از فرمت های قابل قبول:

Application/JSON - Application/XML - Text/HTML - Text/plain

Content-type

برای نشان دادن نوع دیتایی که درrequest body وجود دارد. برای مثال "application/json" نشان می دهد که request body در قالب JSON است. چند نمونه از فرمت های قابل قبول:

Application/JSON - Application/XML - Text/HTML - Text/plain


Authorization:

برای ارائه اطلاعات احراز هویت به سرور استفاده می شود. این به client اجازه می‌دهد تا credential یا token را که هویت و مجوزهای آن را تأیید می کند، وارد کند و دسترسی به resourceها را تضمین کند. Authorization نقش مهمی در اجرای مکانیسم‌های کنترل دسترسی ایفا می‌کند و تضمین می‌کند که فقط clientهای مجاز می‌توانند اقدامات خاصی را انجام دهند یا داده‌های خاصی را از API فرخوانی کنند. چند مثال معمول از این هدر:

  • API key authentication: The client includes an API key in the Authorization header to authenticate itself. The server validates the API key to ensure that the client has the necessary permissions to access the requested resources.
  • Token-based authentication: The client includes an access token in the Authorization header, such as a JSON Web Token (JWT). This token contains information about the client's identity and permissions. The server verifies the token's authenticity and grants access based on the token's claims.
  • OAuth authentication: In scenarios where third-party authentication is required, the Authorization header can be used to send the OAuth token or bearer token. This allows the server to authenticate the client using the OAuth provider and grant access based on the provided token.
  • Role-based access control: The Authorization header can also be used to convey the client's role or specific access level. This information helps the server enforce access control policies and restrict certain actions or resources based on the client's assigned role or privileges.


Cache-Control

دستورالعمل‌هایی را به clinetها و واسطه‌ها (مانند حافظه‌های پنهان) در مورد مدیریت ذخیره‌سازی response ارائه می‌کنند. آنها با کاهش انتقال دیتاهای غیر ضروری و بهبود زمان response، به بهینه سازی عملکرد کمک می کنند.

هنگامی که یک response در حافظه پنهان ذخیره می شود (cached)، body ذخیره شده به requestها بازگردانده می شود، نه اینکه اطلاعات هر بار بازیابی شود. چند مثال از این هدر:

  • public

مشخص می کند که response را می توان ذخیره کرد

  • private: The response can be stored, but not in a shared cache.

مشخص می کند که response را می توان ذخیره کرد اما برای یک کاربر خاص در نظر گرفته شده است.

  • max-age: The time in seconds for which a cached response is acceptable.

حداکثر زمان (بر حسب ثانیه) را مشخص می‌کند که response ذخیره شده در cache قابل قبول است.

  • no-cache: Used by clients to specify that a stored response shouldn’t be used, or by the server shouldn’t use the response for subsequent requests without validation on the origin server.

توسط کلاینت ها برای تعیین اینکه یک response ذخیره شده نباید استفاده شود، یا توسط سرور نباید از response برای requestsهای بعدی بدون اعتبارسنجی در سرور مبدا استفاده کند.

  • no-store: A cache must not store the request or response - if specified by the client or server respectively


۵. موارد پرتکرار در Response Header:

هدرهای response بخشی جدایی ناپذیر از پروتکل HTTP هستند و توسط سرورها برای ارائه اطلاعات اضافی در مورد response ارسال شده به کلاینت استفاده می شوند. response headerها نقش مهمی در انتقال جزئیات مهم در مورد response سرور دارند. می‌توانند شامل اطلاعات مختلفی مانند نوع محتوای response، دستورالعمل‌های حافظه پنهان، اطلاعات سرور و غیره باشند. اینها با request headerها مرتبط هستند زیرا جزئیات مهمی را ارائه می دهند که به کلاینت کمک می کند تا response دریافتی را درک کند و پردازش کند. به عنوان مثال، هدر "Content-Type" کلاینت را در مورد قالب داده های بازگردانده شده (به عنوان مثال، JSON، XML) مطلع می کند و به کلاینت اجازه می دهد تا پاسخ را به طور مناسب تجزیه و مدیریت کند.

Content-type

برای نشان دادن نوع دیتایی که درresponse body وجود دارد. برای مثال "application/json" نشان می دهد که response body در قالب JSON است. چند نمونه از فرمت های قابل قبول:

Application/JSON - Application/XML - Text/HTML - Text/plain

Location

این هدر برای هدایت کلاینت به یک URL دیگر استفاده می شود. کلاینت باید به طور خودکار URL را در Location header دنبال کند. معمولاً برای تغییر مسیرهای HTTP استفاده می شود، مانند زمانی که کاربر فرمی را ارسال می کند و به صفحه تأیید هدایت می شود.

نمونه کد قابل قبول Request Header

POST /api/orders HTTP/1.1
Host: api.amaxon.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
Accept: application/json
User-Agent: AmaxonApp/1.01

نمونه کد قابل قبول Response Header

Content-Type: application/json
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 96


۶. مشخص کردن دیتاهای مورد نیاز در Request Body

هنگامی که شما نیاز به ارسال داده از کلاینت به API دارید، آن را به عنوان Request Body ارسال می‌کنید. این جایی است که ما دیتا و ویژگی‌هایی که می‌خواهیم در request خود ارسال کنیم، مشخص می‌کنیم. بجز متد GET بقیه متدها همیشه request body دارند.

اینکه چه دیتاهایی در request body قرار دهید بستگی به تعریف آبجکتها در API و دیتابیس شما دارد. در API Documentation باید ۳ مورد مشخص شود:
۱. کدام فیلدها اجباری و کدام اختیاری است ۲. شرح هر فیلد ۳. نمونه ای از دیتای ارسالی

ساختار request body

  • بسته به API و نوع دیتا ارسالی، request body را می توان به روش های مختلفی پیاده سازی کرد. اینها سه نوع رایج پیاده سازی هستند:


  • Raw

از نظر فنی می تواند هر نوع رشته ای را در خود جای دهد، اما به طور کلی شامل XML یا JSON می شود، به عنوان مثال. {"firstName":"Pied", "lastName":"Piper"}

  • x-www-form-urlencoded

برای ارسال مقادیر متنی ساده در یک رشته پرس و جو استفاده میشود. مثال key1=value1&key2=value2. در ایت روش همه کارکترها کدگذاری می‌شوند. مثلا فاصله(space) با %20 جایگزین میشه.

  • Binary

برای پیوست کردن تصاویر، فیلم ها، صداها و سایر فایل های غیر متنی استفاده می‌شود.

​انواع دیگر عبارتند از GraphQL و فرم های چند بخشی. فرمت صحیح بستگی به سرور دارد و داکیومنت API همیشه باید به شما بگوید که دقیقاً چگونه دیتا را ارسال کنید که به درستی پردازش شوند.

نمونه ای از یک Request Body

اگر قصد داشته باشیم با متد PUT اطلاعات کاربری را آپدیت کنیم، request body و route آن میتواند بصورت زیر باشد:

GET /users/findByName?name=saeed
{
"Name": "Majid",
"Number": 57,
"Team": "Arsenal"
}
در این مثال اطلاعات هر ۳ فیلدی که در request body مشخض شده است برای کاربری با نام saeed آپدیت می شود. نکته مهم در تعریف request body این است که فقط دیتاهایی را مشخص کنیم که به آنها نیاز است.

۷. تعریف Response Body

درست مانند request body، برای نگهداری و ارسال دیتاهایی که می‌خواهیم به کلاینت ارسال کنیم، استفاده می‌شود. البته در پاسخ به بعضی از requestها به response body نیاز نیست و تنها با ارسال یک status code مشخص میکنیم که درخواست کلاینت انجام شد یا نشد. برای مثال هنگام لاگین به یک سایت تنها نیاز است status code ارسال کنیم و مشخص کنیم که لاگین موفق بود و یا به چه علت لاگین انجام نشد.

متدهای GET همیشه نیاز به یک Response body دارند.

ساختار response body همانند request body است و فقط دیتاهایی که در اینها مشخص میکنیم تفاوت دارد. و نکته اصلی این است که از ارسال دیتاهای غیرضروری از طریق response body خودداری کنید.

۸. انتخاب درست Status Code

نشان می دهد آیا سرور با موفقیت درخواست را انجام داده است یا خیر - و اگر نه، چرا. اولین بخشی از Response که خطا را مشخص میکند و همچنین دولوپرها برای دیباگ کردن به آن توجه میکنند status code ها هستند، در نتیجه انتخاب درست status code ها اهمیت زیادی دارند. حتما صفحه ویکی پدیا را مطالعه کنید.

همانطور که قبلا گفتم هنگام لاگین به یک سایت تنها نیاز است که status code را مشخص کنیم که در اینجا می تواند موارد زیر باشد:

  • 200 OK.
  • 401 Unauthorized.

نکات مهم در تعریف صحیح API

  • اطلاعات اضافی برای API ایجاد نکنید (Don't Create Side Effects on the API)

برای مثال اگر یک کاربر فقط نام یک کاربر را درخواست می‌کند، نام کامل و ID را هم به کاربر ارسال نکنید. فقط همان چیزی که نیاز است. ارسال response body کوچک اهمیت بالایی دارد.

هنگام ایجاد یک API، سعی کنید تا حد امکان همه چیز را در یک تابع تعریف نکنید. اگر وظایف زیادی را به طور همزمان انجام دهد، باید به چند API تقسیم شود.

  • پیاده سازی صفحه بندی

هنگامی که یک میکروسرویس بزرگ ایجاد می‌کنید و Response body یا Response Object بیش از حد بزرگ می‌شود، صفحه‌بندی باعث می‌شود API بتواند مقدار کمی از اطلاعات را برگرداند. صفحه بندی روشی برای جداسازی محتوای دیجیتال به صفحات مختلف در یک وب سایت یا یک Response Object است.

یک پایگاه داده با هفتاد کاربر را تصور کنید. API به جای ارسال پاسخ همه کاربران به یکباره و کند کردن آن، getUsers را فراخوانی می کند.می‌توانید پاسخ را تجزیه کنید، مانند بازگرداندن سی کاربر اول، سی کاربر بعدی و ده کاربر بعدی.

  • از Fragmentation استفاده کنید

هنگامی که یک API به صورت داخلی ارتباط برقرار می کند، response معمولا کوتاه است. اما وقتی response بزرگ باشد، استثناست و وقتی استثنا باشد، یعنی یک مشکلی وجود دارد. این زمانی اتفاق می‌افتد که response از اندازه نرمال خود بیشتر شود (10 کیلوبایت یا 15 کیلوبایت). راه حل در اینجا این است که response را تجزیه کنید و آن را ذره ذره به سرویس دیگری بدهید.





apihttphttp status codehttp methodsresponse header
شاید از این پست‌ها خوشتان بیاید