5 أشياء لم تفعلها من قبل بمواصفات REST

نشرت: 2022-03-11

تعامل معظم مطوري الواجهة الأمامية والخلفية مع مواصفات REST وواجهات برمجة تطبيقات RESTful من قبل. ولكن ليست كل واجهات برمجة تطبيقات RESTful يتم إنشاؤها على قدم المساواة. في الواقع ، نادرًا ما يستريحون على الإطلاق ...

ما هي RESTful API؟

إنها أسطورة.

إذا كنت تعتقد أن مشروعك يحتوي على RESTful API ، فأنت على الأرجح مخطئ. الفكرة وراء RESTful API هي التطوير بطريقة تتبع جميع القواعد والقيود المعمارية الموضحة في مواصفات REST. من الناحية الواقعية ، هذا مستحيل إلى حد كبير في الممارسة.

من ناحية أخرى ، يحتوي REST على الكثير من التعريفات الضبابية والغامضة. على سبيل المثال ، في الممارسة العملية ، يتم استخدام بعض المصطلحات من طريقة HTTP وقواميس أكواد الحالة على عكس الأغراض المقصودة منها ، أو لا يتم استخدامها على الإطلاق.

من ناحية أخرى ، فإن تطوير REST يخلق الكثير من القيود. على سبيل المثال ، يعد استخدام الموارد الذرية دون المستوى الأمثل لواجهات برمجة التطبيقات الواقعية المستخدمة في تطبيقات الأجهزة المحمولة. يؤدي الرفض الكامل لتخزين البيانات بين الطلبات إلى حظر آلية "جلسة المستخدم" التي تظهر في كل مكان تقريبًا.

لكن انتظر ، الأمر ليس بهذا السوء!

ما الذي تحتاجه لمواصفات REST API؟

على الرغم من هذه العيوب ، مع اتباع نهج معقول ، لا يزال REST مفهومًا رائعًا لإنشاء واجهات برمجة تطبيقات رائعة حقًا. يمكن أن تكون واجهات برمجة التطبيقات هذه متسقة ولها هيكل واضح وتوثيق جيد وتغطية اختبار وحدة عالية. يمكنك تحقيق كل هذا من خلال مواصفات API عالية الجودة.

عادةً ما ترتبط مواصفات REST API بوثائقها . بخلاف المواصفات - الوصف الرسمي لواجهة برمجة التطبيقات - يُقصد بالوثائق أن تكون سهلة القراءة: على سبيل المثال ، يقرأها مطورو تطبيقات الهاتف المحمول أو الويب التي تستخدم واجهة برمجة التطبيقات الخاصة بك.

الوصف الصحيح لواجهة برمجة التطبيقات لا يتعلق فقط بكتابة وثائق API بشكل جيد. في هذه المقالة أريد أن أشارك أمثلة حول كيف يمكنك:

  • اجعل اختبارات الوحدة الخاصة بك أبسط وأكثر موثوقية ؛
  • إعداد معالجة مدخلات المستخدم والتحقق من صحتها ؛
  • أتمتة التسلسل وضمان اتساق الاستجابة ؛ وحتى
  • استمتع بفوائد الكتابة الثابتة.

لكن أولاً ، لنبدأ بمقدمة إلى عالم مواصفات API.

OpenAPI

يعد OpenAPI حاليًا التنسيق الأكثر قبولًا على نطاق واسع لمواصفات REST API. المواصفات مكتوبة في ملف واحد بتنسيق JSON أو YAML يتكون من ثلاثة أقسام:

  1. رأس مع اسم API ووصف وإصدار بالإضافة إلى أي معلومات إضافية.
  2. أوصاف جميع الموارد ، بما في ذلك المعرفات وطرق HTTP وجميع معلمات الإدخال ورموز الاستجابة وأنواع بيانات الجسم ، مع روابط للتعريفات.
  3. جميع التعريفات التي يمكن استخدامها للإدخال أو الإخراج ، بتنسيق مخطط JSON (والذي ، نعم ، يمكن أيضًا تمثيله في YAML.)

بنية OpenAPI لها عيبان هامان: إنها معقدة للغاية وفي بعض الأحيان زائدة عن الحاجة. يمكن أن يكون لمشروع صغير مواصفات JSON لآلاف السطور. يصبح الاحتفاظ بهذا الملف يدويًا مستحيلًا. يعد هذا تهديدًا كبيرًا لفكرة تحديث المواصفات أثناء تطوير واجهة برمجة التطبيقات.

هناك عدة برامج تحرير تسمح لك بوصف واجهة برمجة التطبيقات (API) وإنتاج إخراج OpenAPI. تشمل الخدمات الإضافية والحلول السحابية المستندة إليها Swagger و Apiary و Stoplight و Restlet وغيرها الكثير.

ومع ذلك ، كانت هذه الخدمات غير مريحة بالنسبة لي بسبب تعقيد التحرير السريع للمواصفات ومواءمتها مع تغييرات الكود. بالإضافة إلى ذلك ، كانت قائمة الميزات تعتمد على خدمة معينة. على سبيل المثال ، يعد إنشاء اختبارات وحدة كاملة بناءً على أدوات الخدمة السحابية أقرب إلى المستحيل. في حين أن إنشاء الكود والاستهزاء بنقاط النهاية تبدو عملية ، إلا أنها في الغالب غير مجدية من الناحية العملية. هذا في الغالب لأن سلوك نقطة النهاية يعتمد عادةً على أشياء مختلفة مثل أذونات المستخدم ومعلمات الإدخال ، والتي قد تكون واضحة لمهندس واجهة برمجة التطبيقات ولكن ليس من السهل إنشاؤها تلقائيًا من مواصفات OpenAPI.

تينيسبيك

في هذه المقالة ، سأستخدم أمثلة تستند إلى تنسيق تعريف REST API الخاص بي ، tinyspec . تتكون التعريفات من ملفات صغيرة ذات بناء جملة بديهي. يصفون نقاط النهاية ونماذج البيانات المستخدمة في المشروع. يتم تخزين الملفات بجانب الكود ، مما يوفر مرجعًا سريعًا والقدرة على التحرير أثناء كتابة التعليمات البرمجية. يتم تجميع Tinyspec تلقائيًا في تنسيق OpenAPI كامل يمكن استخدامه على الفور في مشروعك.

سأستخدم أيضًا أمثلة Node.js (Koa و Express) و Ruby on Rails ، لكن الممارسات التي سأوضحها قابلة للتطبيق على معظم التقنيات ، بما في ذلك Python و PHP و Java.

حيث صخور مواصفات API

الآن بعد أن أصبح لدينا بعض الخلفية ، يمكننا استكشاف كيفية تحقيق أقصى استفادة من واجهة برمجة التطبيقات المحددة بشكل صحيح.

1. اختبارات وحدة نقطة النهاية

يعتبر التطوير المدفوع بالسلوك (BDD) مثاليًا لتطوير واجهات برمجة تطبيقات REST. من الأفضل كتابة اختبارات الوحدة ليس لفئات أو نماذج أو وحدات تحكم منفصلة ، ولكن لنقاط نهاية معينة. في كل اختبار تقوم بمحاكاة طلب HTTP حقيقي والتحقق من استجابة الخادم. بالنسبة إلى Node.js ، توجد حزم supertest و chai-http لمحاكاة الطلبات ، أما بالنسبة إلى Ruby on Rails ، فهناك حزم محمولة جواً.

لنفترض أن لدينا مخطط User ونقطة نهاية GET /users التي تُرجع جميع المستخدمين. إليك بعض بناء جملة tinyspec الذي يصف هذا:

 # user.models.tinyspec User {name, isAdmin: b, age?: i} # users.endpoints.tinyspec GET /users => {users: User[]}

وإليك كيفية كتابة الاختبار المقابل:

Node.js

 describe('/users', () => { it('List all users', async () => { const { status, body: { users } } = request.get('/users'); expect(status).to.equal(200); expect(users[0].name).to.be('string'); expect(users[0].isAdmin).to.be('boolean'); expect(users[0].age).to.be.oneOf(['boolean', null]); }); });

روبي على القضبان

 describe 'GET /users' do it 'List all users' do get '/users' expect_status(200) expect_json_types('users.*', { name: :string, isAdmin: :boolean, age: :integer_or_null, }) end end

عندما يكون لدينا بالفعل المواصفات التي تصف استجابات الخادم ، يمكننا تبسيط الاختبار والتحقق فقط مما إذا كانت الاستجابة تتبع المواصفات. يمكننا استخدام نماذج tinyspec ، كل منها يمكن تحويله إلى مواصفات OpenAPI التي تتبع تنسيق مخطط JSON.

يمكن التحقق من صحة أي كائن حرفي في JS (أو Hash في Ruby ، ​​و dict في Python ، والمصفوفة الترابطية في PHP ، وحتى Map في Java) من أجل التوافق مع مخطط JSON. توجد أيضًا مكونات إضافية مناسبة لاختبار الأطر ، على سبيل المثال jest-ajv (npm) و chai-ajv-json-schema (npm) و json_matchers لـ RSpec (rubygem).

قبل استخدام المخططات ، دعنا نستوردها في المشروع. أولاً ، قم بإنشاء ملف openapi.json بناءً على مواصفات tinyspec (يمكنك القيام بذلك تلقائيًا قبل كل تشغيل اختباري):

 tinyspec -j -o openapi.json

Node.js

يمكنك الآن استخدام JSON الذي تم إنشاؤه في المشروع والحصول على مفتاح definitions منه. يحتوي هذا المفتاح على جميع مخططات JSON. قد تحتوي المخططات على مراجع تبادلية ( $ref ) ، لذلك إذا كان لديك أي مخططات مضمنة (على سبيل المثال ، Blog {posts: Post[]} ) ، فأنت بحاجة إلى إلغاء تغليفها لاستخدامها في التحقق من الصحة. لهذا ، سوف نستخدم json-schema-deref-sync (npm).

 import deref from 'json-schema-deref-sync'; const spec = require('./openapi.json'); const schemas = deref(spec).definitions; describe('/users', () => { it('List all users', async () => { const { status, body: { users } } = request.get('/users'); expect(status).to.equal(200); // Chai expect(users[0]).to.be.validWithSchema(schemas.User); // Jest expect(users[0]).toMatchSchema(schemas.User); }); });

روبي على القضبان

تعرف الوحدة النمطية json_matchers كيفية التعامل مع مراجع $ref ، ولكنها تتطلب ملفات مخطط منفصلة في الموقع المحدد ، لذلك ستحتاج إلى تقسيم ملف swagger.json إلى عدة ملفات أصغر أولاً:

 # ./spec/support/json_schemas.rb require 'json' require 'json_matchers/rspec' JsonMatchers.schema_root = 'spec/schemas' # Fix for json_matchers single-file restriction file = File.read 'spec/schemas/openapi.json' swagger = JSON.parse(file, symbolize_names: true) swagger[:definitions].keys.each do |key| File.open("spec/schemas/#{key}.json", 'w') do |f| f.write(JSON.pretty_generate({ '$ref': "swagger.json#/definitions/#{key}" })) end end

إليك كيف سيبدو الاختبار:

 describe 'GET /users' do it 'List all users' do get '/users' expect_status(200) expect(result[:users][0]).to match_json_schema('User') end end

كتابة الاختبارات بهذه الطريقة مريحة للغاية. خاصة إذا كان IDE الخاص بك يدعم إجراء الاختبارات وتصحيح الأخطاء (على سبيل المثال ، WebStorm و RubyMine و Visual Studio). بهذه الطريقة يمكنك تجنب استخدام برامج أخرى ، وتقتصر دورة تطوير واجهة برمجة التطبيقات بالكامل على ثلاث خطوات:

  1. تصميم المواصفات في ملفات تينيسبيك.
  2. كتابة مجموعة كاملة من الاختبارات لنقاط النهاية المضافة / المحررة.
  3. تنفيذ الكود الذي يرضي الاختبارات.

2. التحقق من صحة بيانات الإدخال

لا يصف OpenAPI تنسيق الاستجابة فحسب ، بل يصف أيضًا بيانات الإدخال. يتيح لك ذلك التحقق من صحة البيانات التي يرسلها المستخدم في وقت التشغيل والتأكد من تحديثات قاعدة البيانات المتسقة والآمنة.

لنفترض أن لدينا المواصفات التالية ، والتي تصف تصحيح سجل المستخدم وجميع الحقول المتاحة التي يُسمح بتحديثها:

 # user.models.tinyspec UserUpdate !{name?, age?: i} # users.endpoints.tinyspec PATCH /users/:id {user: UserUpdate} => {success: b}

في السابق ، استكشفنا المكونات الإضافية للتحقق من الصحة أثناء الاختبار ، ولكن بالنسبة للحالات العامة ، توجد وحدات التحقق من صحة ajv (npm) و json-schema (rubygem). دعنا نستخدمها لكتابة وحدة تحكم مع التحقق من الصحة:

Node.js (Koa)

هذا مثال لـ Koa ، خليفة Express - لكن كود Express المكافئ سيبدو مشابهًا.

 import Router from 'koa-router'; import Ajv from 'ajv'; import { schemas } from './schemas'; const router = new Router(); // Standard resource update action in Koa. router.patch('/:id', async (ctx) => { const updateData = ctx.body.user; // Validation using JSON schema from API specification. await validate(schemas.UserUpdate, updateData); const user = await User.findById(ctx.params.id); await user.update(updateData); ctx.body = { success: true }; }); async function validate(schema, data) { const ajv = new Ajv(); if (!ajv.validate(schema, data)) { const err = new Error(); err.errors = ajv.errors; throw err; } }

في هذا المثال ، يعرض الخادم استجابة 500 Internal Server Error إذا كان الإدخال لا يتطابق مع المواصفات. لتجنب ذلك ، يمكننا اكتشاف خطأ المدقق وتشكيل إجابتنا الخاصة التي ستحتوي على معلومات أكثر تفصيلاً حول الحقول المحددة التي فشلت في التحقق من الصحة ، واتباع المواصفات.

دعنا نضيف تعريف FieldsValidationError :

 # error.models.tinyspec Error {error: b, message} InvalidField {name, message} FieldsValidationError < Error {fields: InvalidField[]}

والآن دعنا ندرجها كواحدة من ردود نقطة النهاية المحتملة:

 # users.endpoints.tinyspec PATCH /users/:id {user: UserUpdate} => 200 {success: b} => 422 FieldsValidationError

يتيح لك هذا الأسلوب كتابة اختبارات الوحدة التي تختبر صحة سيناريوهات الخطأ عندما تأتي البيانات غير الصالحة من العميل.

3. نموذج التسلسل

تستخدم جميع أطر عمل الخوادم الحديثة تقريبًا تعيين ارتباط الكائنات (ORM) بطريقة أو بأخرى. هذا يعني أن غالبية الموارد التي تستخدمها API يتم تمثيلها بواسطة النماذج ومثيلاتها ومجموعاتها.

تسمى عملية تكوين تمثيلات JSON لهذه الكيانات التي سيتم إرسالها في الاستجابة بالتسلسل .

هناك عدد من المكونات الإضافية لإجراء التسلسل: على سبيل المثال ، Sequelize-to-json (npm) ، و act_as_api (rubygem) ، و jsonapi-rails (rubygem). بشكل أساسي ، تسمح لك هذه المكونات الإضافية بتوفير قائمة الحقول الخاصة بنموذج معين يجب تضمينه في كائن JSON ، بالإضافة إلى القواعد الإضافية. على سبيل المثال ، يمكنك إعادة تسمية الحقول وحساب قيمها ديناميكيًا.

يصبح الأمر أكثر صعوبة عندما تحتاج إلى عدة تمثيلات JSON مختلفة لنموذج واحد ، أو عندما يحتوي الكائن على كيانات متداخلة - ارتباطات. ثم تبدأ في الحاجة إلى ميزات مثل ربط الوراثة وإعادة الاستخدام والمسلسل.

توفر الوحدات النمطية المختلفة حلولًا مختلفة ، ولكن دعنا نفكر في هذا: هل يمكن أن تساعد المواصفات مرة أخرى؟ بشكل أساسي جميع المعلومات حول متطلبات تمثيلات JSON ، جميع مجموعات الحقول الممكنة ، بما في ذلك الكيانات المضمنة ، موجودة بالفعل فيها. وهذا يعني أنه يمكننا كتابة مسلسِل آلي واحد.

اسمحوا لي أن أقدم الوحدة الصغيرة للتسلسل التسلسلي (npm) ، والتي تدعم القيام بذلك لنماذج Sequelize. يقبل مثيل نموذج أو مصفوفة ، والمخطط المطلوب ، ثم يتكرر من خلاله لبناء الكائن المتسلسل. كما أنها تمثل جميع الحقول المطلوبة وتستخدم المخططات المتداخلة للكيانات المرتبطة بها.

لذلك ، لنفترض أننا بحاجة إلى إعادة جميع المستخدمين الذين لديهم منشورات في المدونة ، بما في ذلك التعليقات على هذه المنشورات ، من واجهة برمجة التطبيقات. دعنا نصفها بالمواصفات التالية:

 # models.tinyspec Comment {authorId: i, message} Post {topic, message, comments?: Comment[]} User {name, isAdmin: b, age?: i} UserWithPosts < User {posts: Post[]} # blogUsers.endpoints.tinyspec GET /blog/users => {users: UserWithPosts[]}

يمكننا الآن إنشاء الطلب باستخدام Sequelize وإرجاع الكائن المتسلسل الذي يتوافق مع المواصفات الموضحة أعلاه تمامًا:

 import Router from 'koa-router'; import serialize from 'sequelize-serialize'; import { schemas } from './schemas'; const router = new Router(); router.get('/blog/users', async (ctx) => { const users = await User.findAll({ include: [{ association: User.posts, required: true, include: [Post.comments] }] }); ctx.body = serialize(users, schemas.UserWithPosts); });

هذا شبه سحري ، أليس كذلك؟

4. الكتابة الثابتة

إذا كنت رائعًا بما يكفي لاستخدام TypeScript أو Flow ، فربما تكون قد سألت بالفعل ، "ماذا عن الأنواع الثابتة الثمينة الخاصة بي؟!" باستخدام الوحدات النمطية sw2dts أو swagger-to-flowtype ، يمكنك إنشاء جميع الأنواع الثابتة اللازمة بناءً على مخططات JSON واستخدامها في الاختبارات ووحدات التحكم والمسلسلات.

 tinyspec -j sw2dts ./swagger.json -o Api.d.ts --namespace Api

الآن يمكننا استخدام الأنواع في وحدات التحكم:

 router.patch('/users/:id', async (ctx) => { // Specify type for request data object const userData: Api.UserUpdate = ctx.request.body.user; // Run spec validation await validate(schemas.UserUpdate, userData); // Query the database const user = await User.findById(ctx.params.id); await user.update(userData); // Return serialized result const serialized: Api.User = serialize(user, schemas.User); ctx.body = { user: serialized }; });

والاختبارات:

 it('Update user', async () => { // Static check for test input data. const updateData: Api.UserUpdate = { name: MODIFIED }; const res = await request.patch('/users/1', { user: updateData }); // Type helper for request response: const user: Api.User = res.body.user; expect(user).to.be.validWithSchema(schemas.User); expect(user).to.containSubset(updateData); });

لاحظ أنه يمكن استخدام تعريفات الأنواع التي تم إنشاؤها ليس فقط في مشروع API ، ولكن أيضًا في مشاريع تطبيق العميل لوصف الأنواع في الوظائف التي تعمل مع API. (سيكون المطورون الزاويون سعداء بشكل خاص بهذا الأمر).

5. صب أنواع سلاسل الاستعلام

إذا كانت واجهة برمجة التطبيقات الخاصة بك تستهلك لسبب ما الطلبات مع نوع application/x-www-form-urlencoded MIME بدلاً من application/json ، سيبدو نص الطلب كما يلي:

 param1=value&param2=777&param3=false

الشيء نفسه ينطبق على معلمات الاستعلام (على سبيل المثال ، في طلبات GET ). في هذه الحالة ، سيفشل خادم الويب في التعرف تلقائيًا على الأنواع: ستكون جميع البيانات بتنسيق سلسلة ، لذلك بعد التحليل ستحصل على هذا الكائن:

 { param1: 'value', param2: '777', param3: 'false' }

في هذه الحالة ، سيفشل الطلب في التحقق من صحة المخطط ، لذلك تحتاج إلى التحقق من تنسيقات المعلمات الصحيحة يدويًا ونقلها إلى الأنواع الصحيحة.

كما يمكنك التخمين ، يمكنك القيام بذلك باستخدام مخططاتنا القديمة الجيدة من المواصفات. لنفترض أن لدينا نقطة النهاية والمخطط التالي:

 # posts.endpoints.tinyspec GET /posts?PostsQuery # post.models.tinyspec PostsQuery { search, limit: i, offset: i, filter: { isRead: b } }

إليك كيف يبدو الطلب إلى نقطة النهاية هذه:

 GET /posts?search=needle&offset=10&limit=1&filter[isRead]=true

لنكتب وظيفة castQuery جميع المعلمات إلى الأنواع المطلوبة:

 function castQuery(query, schema) { _.mapValues(query, (value, key) => { const { type } = schema.properties[key] || {}; if (!value || !type) { return value; } switch (type) { case 'integer': return parseInt(value, 10); case 'number': return parseFloat(value); case 'boolean': return value !== 'false'; default: return value; } }); }

يتوفر تنفيذ أكمل مع دعم للمخططات المتداخلة والمصفوفات والأنواع null في الوحدة النمطية cast-with-schema (npm). الآن دعنا نستخدمه في الكود الخاص بنا:

 router.get('/posts', async (ctx) => { // Cast parameters to expected types const query = castQuery(ctx.query, schemas.PostsQuery); // Run spec validation await validate(schemas.PostsQuery, query); // Query the database const posts = await Post.search(query); // Return serialized result ctx.body = { posts: serialize(posts, schemas.Post) }; });

لاحظ أن ثلاثة من الأسطر الأربعة للكود تستخدم مخططات المواصفات.

أفضل الممارسات

هناك عدد من أفضل الممارسات التي يمكننا اتباعها هنا.

استخدم إنشاء وتحرير المخططات المنفصلة

عادةً ما تكون المخططات التي تصف استجابات الخادم مختلفة عن تلك التي تصف المدخلات وتستخدم لإنشاء النماذج وتحريرها. على سبيل المثال ، يجب أن تكون قائمة الحقول المتوفرة في طلبات POST و PATCH محدودة للغاية ، وعادةً ما يتم وضع علامة اختيارية على جميع الحقول في PATCH . يمكن أن تكون المخططات التي تصف الاستجابة أكثر حرية.

عندما تقوم بإنشاء نقاط نهاية CRUDL تلقائيًا ، يستخدم tinyspec إصلاحات postfixes New Update . يمكن تعريف مخططات User* بالطريقة التالية:

 User {id, email, name, isAdmin: b} UserNew !{email, name} UserUpdate !{email?, name?}

حاول عدم استخدام نفس المخططات لأنواع الإجراءات المختلفة لتجنب مشكلات الأمان العرضية بسبب إعادة استخدام أو توريث المخططات القديمة.

اتبع اصطلاحات تسمية المخطط

قد يختلف محتوى نفس الطرازات باختلاف نقاط النهاية. استخدم With* و For* postfixes في أسماء المخططات لإظهار الاختلاف والغرض. في tinyspec ، يمكن أن ترث النماذج أيضًا من بعضها البعض. علي سبيل المثال:

 User {name, surname} UserWithPhotos < User {photos: Photo[]} UserForAdmin < User {id, email, lastLoginAt: d}

يمكن أن تتنوع الإصلاحات اللاحقة والجمع بينها. يجب أن يظل اسمهم يعكس الجوهر ويجعل الوثائق أسهل في القراءة.

فصل نقاط النهاية بناءً على نوع العميل

غالبًا ما تقوم نفس نقطة النهاية بإرجاع بيانات مختلفة بناءً على نوع العميل ، أو دور المستخدم الذي أرسل الطلب. على سبيل المثال ، يمكن أن تختلف نقاط نهاية GET /users و GET /messages Messages بشكل كبير لمستخدمي تطبيقات الهاتف المحمول ومديري المكاتب الخلفية. يمكن أن يكون تغيير اسم نقطة النهاية عبئًا.

لوصف نفس نقطة النهاية عدة مرات ، يمكنك إضافة نوعها بين قوسين بعد المسار. هذا أيضًا يجعل استخدام العلامة أمرًا سهلاً: يمكنك تقسيم وثائق نقطة النهاية إلى مجموعات ، كل منها مخصص لمجموعة عملاء API معينة. علي سبيل المثال:

 Mobile app: GET /users (mobile) => UserForMobile[] CRM admin panel: GET /users (admin) => UserForAdmin[]

أدوات توثيق REST API

بعد الحصول على المواصفات بتنسيق tinyspec أو OpenAPI ، يمكنك إنشاء وثائق جميلة المظهر بتنسيق HTML ونشرها. هذا سيجعل المطورين الذين يستخدمون API الخاص بك سعداء ، ومن المؤكد أنه يدقق في ملء قالب وثائق REST API يدويًا.

بصرف النظر عن الخدمات السحابية المذكورة سابقًا ، هناك أدوات CLI تقوم بتحويل OpenAPI 2.0 إلى HTML و PDF ، والتي يمكن نشرها على أي استضافة ثابتة. وهنا بعض الأمثلة:

  • bootprint-openapi (npm ، تستخدم افتراضيًا في tinyspec)
  • swagger2markup-cli (جرة ، هناك مثال على الاستخدام ، سيتم استخدامها في سحابة tinyspec)
  • إعادة توجيه CLI (نانومتر)
  • widdershins (نانومتر)

هل لديك المزيد من الأمثلة؟ مشاركتها في التعليقات.

للأسف ، على الرغم من إصدار OpenAPI 3.0 قبل عام ، لا يزال دعمًا ضعيفًا وفشلت في العثور على أمثلة مناسبة للوثائق التي تستند إليها في كل من الحلول السحابية وأدوات CLI. للسبب نفسه ، لا يدعم tinyspec OpenAPI 3.0 حتى الآن.

النشر على جيثب

إحدى أبسط الطرق لنشر الوثائق هي صفحات GitHub. ما عليك سوى تمكين دعم الصفحات الثابتة لمجلد /docs الخاص بك في إعدادات المستودع وتخزين وثائق HTML في هذا المجلد.

استضافة وثائق HTML لمواصفات REST الخاصة بك من مجلد / docs الخاص بك عبر GitHub Pages.

يمكنك إضافة الأمر لإنشاء التوثيق من خلال tinyspec أو أداة CLI مختلفة في ملف scripts/package.json لتحديث التوثيق تلقائيًا بعد كل التزام:

 "scripts": { "docs": "tinyspec -h -o docs/", "precommit": "npm run docs" }

التكامل المستمر

يمكنك إضافة إنشاء وثائق إلى دورة CI الخاصة بك ونشرها ، على سبيل المثال ، إلى Amazon S3 تحت عناوين مختلفة اعتمادًا على البيئة أو إصدار واجهة برمجة التطبيقات (مثل /docs/2.0 و /docs/stable stabil و /docs/staging .)

سحابة Tinyspec

إذا كنت تحب بناء جملة tinyspec ، فيمكنك أن تصبح من أوائل المتبنين لـ tinyspec.cloud. نحن نخطط لبناء خدمة سحابية تعتمد عليها و CLI للنشر الآلي للوثائق مع مجموعة واسعة من القوالب والقدرة على تطوير قوالب مخصصة.

مواصفات REST: أسطورة رائعة

ربما يكون تطوير واجهة برمجة تطبيقات REST أحد أكثر العمليات متعة في تطوير خدمات الويب والجوّال الحديثة. لا يوجد متصفح ، ونظام تشغيل ، وحدائق حيوانات بحجم الشاشة ، وكل شيء تحت سيطرتك بالكامل ، في متناول يدك.

أصبحت هذه العملية أسهل من خلال دعم الأتمتة والمواصفات الحديثة. تصبح واجهة برمجة التطبيقات التي تستخدم الأساليب التي وصفتها منظمة جيدًا وشفافة وموثوقة.

خلاصة القول ، إذا كنا نصنع أسطورة ، فلماذا لا نجعلها أسطورة رائعة؟

ذات صلة: ActiveResource.js ORM: إنشاء حزمة JavaScript SDK قوية لواجهة برمجة تطبيقات JSON الخاصة بك ، بسرعة