Художественный архитектурный дизайн REST API: что нужно, а что нет.

Когда мы думаем о разработке RESTful API, на ум часто приходит термин HATEOAS (Hypermedia as Engine of Application State). HATEOAS позволяет API управлять навигацией клиента по приложению, включая гиперссылки в ответы API. Хотя HATEOAS — мощная концепция, существует еще один подход к разработке RESTful API, заслуживающий внимания: API, управляемые гипертекстом.

Понимание API, управляемых гипертекстом

API, управляемые гипертекстом, как следует из названия, используют гипертекст и гиперссылки для управления взаимодействием клиента с API. В отличие от традиционных API, которые требуют от клиентов предварительного знания URI ресурсов и действий, API на основе гипертекста предоставляют ссылки в ответах API, которые позволяют клиентам перемещаться по ресурсам и обнаруживать их.

В этом подходе API действует как своего рода «гипермедийный документ», который не только предоставляет данные, но также включает ссылки на связанные ресурсы и действия, которые можно выполнить. Это позволяет клиентам динамически исследовать API, не полагаясь на жестко закодированные URL-адреса или предопределенные пути навигации.

Теперь, прежде чем вы продолжите чтение, вам нужно установить несколько вещей, чтобы начать тестирование кодов в каждом примере.

  1. Убедитесь, что на вашем компьютере установлены Node.js и npm. Вы можете скачать и установить Node.js с официального сайта: https://nodejs.org или NPM с https://docs.npmjs.com/downloading-and-installing-node-js-and-npm.
  2. Создайте новый каталог для вашего проекта.
  3. Откройте терминал или командную строку и перейдите в каталог проекта.
  4. Скопируйте пример кода в новый файл и сохраните его с расширением .js, например ecommerce.js. В терминале или командной строке установите необходимые зависимости, выполнив следующую команду:

экспресс-установка npm

5. После завершения установки запустите сервер, выполнив следующую команду:

узел электронной коммерции.js

6. Вы должны увидеть сообщение о том, что сервер работает на определенном порту (в данном случае 3000).

7. Откройте веб-браузер и перейдите по адресу http://localhost:3000/products, чтобы проверить конечную точку списка продуктов.

Вы должны увидеть ответ JSON, содержащий информацию о доступных продуктах.

8. Попробуйте получить доступ к другим конечным точкам, таким как /cart, /cart/checkout и /cart/payment_infoдля тестирования различных функций платформы электронной коммерции.

Не стесняйтесь исследовать код и вносить изменения в соответствии с вашими потребностями. Вы можете добавлять новые маршруты, реализовывать функции добавления/удаления товаров из корзины или интегрироваться с базой данных для сохранения данных.

Обратите внимание, что это базовый пример для целей тестирования. В реальном сценарии вам нужно будет рассмотреть дополнительные меры безопасности, обрабатывать операции с базой данных и обрабатывать аутентификацию/авторизацию пользователей.

Переосмысление взаимодействия с API

  1. Представьте себе RESTful API для платформы электронной коммерции. Традиционно клиенту необходимо знать конкретные URI для получения списка продуктов, добавления товаров в корзину и проверки. При использовании API, управляемого гипертекстом, сам ответ API содержит гиперссылки для этих и других действий.

Например, вместо того, чтобы полагаться на фиксированный URL-адрес для получения продуктов, ответ API может включать ссылку с типом отношения "products", по которой клиент может перейти, чтобы получить список доступных продуктов. Точно так же ответ может содержать ссылки для добавления товаров в корзину или перехода к оформлению заказа.

Давайте посмотрим некоторые коды.

const express = require('express'); 
const app = express(); 
const PORT = 3000; 

app.get('/products', (req, res) => { 
const productData = [{ 
  id: '1', 
  name: 'Product 1', 
  description: 'This is product 1', 
  price: 10.99, 
  imageLink: 'https://via.placeholder.com/150', 
  addToCartLink: '/cart/add/1' }, 

{ 
  id: '2', 
  name: 'Product 2', 
  description: 'This is product 2', 
  price: 19.99, 
  imageLink: 'https://via.placeholder.com/150', 
  addToCartLink: '/cart/add/2' 
}]; 

  res.json(productData); 
}); 

app.get('/cart', (req, res) => {
 
const cartData = { 
  items: [ { 
  id: '1', 
  name: 'Product 1', 
  description: 'This is product 1', 
  price: 10.99, 
  quantity: 2, 
  imageLink: 'https://via.placeholder.com/150', 
  removeFromCartLink: '/cart/remove/1' } ], 
  subTotal: 21.98, 
  tax: 1.77, 
  total: 23.75, 
  checkoutLink: '/cart/checkout' 
}; 

res.json(cartData); 
}); 


app.get('/cart/checkout', (req, res) => {

const checkoutData = { 
  firstName: 'John', 
  lastName: 'Doe', 
  email: '[email protected]', 
  address: '123 Main St.',
  city: 'Anytown', 
  state: 'CA', 
  zipCode: '90210', 
  paymentInfoLink: '/cart/payment_info' 
}; 

res.json(checkoutData); 
}); 

app.get('/cart/payment_info', (req, res) => {
 
const paymentData = { 
  cardNumber: '**** **** **** 1234', 
  expDate: '06/25', cvv: '123', 
  paymentLink: '/cart/submit_payment' 
}; 
res.json(paymentData); 
}); 


app.post('/cart/submit_payment', (req, res) => { // handle payment submission 

res.sendStatus(200); }); 

app.listen(PORT, () => { 
console.log(`Server running on port ${PORT}`); 
});

В приведенном выше примере запрос GET к /products возвращает информацию о доступных продуктах, включая гиперссылки для добавления каждого продукта в корзину. Запрос GET к /cart возвращает информацию о корзине, включая товары в корзине, промежуточную сумму, налог и гиперссылку на оформление заказа. Запрос GET к /cart/checkout возвращает информацию об оплате, такую ​​как информация о счете и доставке, а также гиперссылку для ввода платежной информации. Запрос GET к /cart/payment_info возвращает форму для ввода платежной информации и гиперссылку для отправки платежной информации.

Разбивая общий пользовательский поток на более мелкие взаимодействия с ресурсами, каждое из которых имеет гиперссылки на связанные ресурсы, эта платформа электронной коммерции может быть разработана так, чтобы быть более гибкой и адаптируемой, позволяя клиентам более динамично взаимодействовать с API.

2. Другой пример. Давайте рассмотрим API для платформы социальной сети. Традиционный RESTful API для этой платформы может иметь конечные точки для получения пользователей, сообщений и комментариев с определенными URL-адресами и маршрутами для каждого из этих ресурсов.

Однако управляемый гипертекстом API для этой платформы будет включать в ответы гиперссылки, которые позволят клиентам перемещаться и взаимодействовать с API более динамичным образом.

Например, ответ для получения пользователя может включать не только информацию о профиле пользователя, но также гиперссылки на сообщения пользователя, подписчиков и список подписчиков. Вместо того, чтобы требовать от клиентов знать URL-адреса этих ресурсов и выполнять несколько вызовов API для их получения, клиенты могут просто перейти по гиперссылкам для доступа к дополнительной информации и ресурсам.

Точно так же ответ на получение сообщения может включать гиперссылки на автора сообщения, комментарии и связанные сообщения. Клиенты могут перейти по этим ссылкам, чтобы изучить контекст сообщения и использовать другие соответствующие ресурсы.

Включая гиперссылки в ответы, управляемый гипертекстом API для платформы социальной сети может сделать взаимодействие с пользователем более интерактивным и бесшовным. Клиенты могут исследовать API и взаимодействовать с ним более естественным и интуитивно понятным способом, не полагаясь на предварительное знание конкретных URL-адресов и API.

Получите код этой иллюстрации;

const express = require('express'); 
const app = express();
 
const PORT = 3000; 

app.get('/users/:id', (req, res) => { 

  const userId = req.params.id; 

  const userData = { 
   id: userId, 
   name: 'John Doe', 
   bio: 'Software developer and music lover', 
   postsLink: `/users/${userId}/posts`, 
   followersLink: `/users/${userId}/followers`, 
   followingLink: `/users/${userId}/following` 
};
   res.json(userData); 
}); 


app.get('/users/:id/posts', (req, res) => { 

   const userId = req.params.id; 

   const postsData = [ 
{ 
   id: '1', 
   authorId: userId, 
   content: 'My first post', 
   commentsLink: `/posts/1/comments`, 
   relatedPostsLink: `/users/${userId}/related_posts` 
}, 
{ 
   id: '2', 
   authorId: userId, 
   content: 'My second post', 
   commentsLink: `/posts/2/comments`, 
   relatedPostsLink: `/users/${userId}/related_posts` 
  } 
]; 

res.json(postsData); }); // other endpoints for comments, following, related posts, etc. 


app.listen(PORT, () => { 
console.log(`Server running on port ${PORT}`); 
});

В приведенном выше примере запрос GET к /users/:id возвращает информацию о конкретном пользователе, включая гиперссылки для доступа к его сообщениям, подписчикам и списку подписчиков. Запрос GET к /users/:id/posts возвращает сообщения пользователя вместе с гиперссылками для доступа к комментариям и связанным сообщениям.

Включая гиперссылки в ответы, клиенты могут динамически перемещаться и взаимодействовать с API, не полагаясь на жестко заданные URL-адреса или предопределенные пути навигации. Это упрощает разработку клиента и способствует ослаблению связи между клиентскими и серверными компонентами.

Преимущества гипертекстовых API

Улучшенная обнаруживаемость

API-интерфейсы на основе гипертекста улучшают возможности обнаружения, предоставляя клиентам дорожную карту для изучения доступных ресурсов и действий. Клиентам больше не нужно полагаться на документацию API или предварительные знания для навигации по API. Они могут просто переходить по ссылкам и позволить API направлять их.

Гибкость и адаптивность

Используя гиперссылки для управления взаимодействием, API-интерфейсы на основе гипертекста становятся более гибкими и адаптируемыми. Добавление или изменение ресурсов и действий не требует изменения клиентского кода, поскольку клиенты могут динамически обнаруживать новые функции и взаимодействовать с ними с помощью гиперссылок, предоставленных в ответах API.

Слабая связь

API, управляемые гипертекстом, способствуют слабой связи между клиентом и API. Клиенту не нужно иметь жестко закодированные сведения об URL-адресах ресурсов или конкретных маршрутах API. Вместо этого он полагается на гиперссылки, предоставляемые API, для навигации и взаимодействия. Такое разделение делает API более устойчивым к будущим изменениям и упрощает развитие как клиентских, так и серверных компонентов.

Упрощенная клиентская разработка

Клиенты, взаимодействующие с гипертекстовыми API, могут больше сосредоточиться на бизнес-логике и взаимодействии с пользователем, поскольку они могут делегировать аспекты навигации и взаимодействия самому API. Это может упростить разработку клиента, снизить сложность и улучшить ремонтопригодность.

Заключение

В то время как HATEOAS является хорошо известным подходом к разработке RESTful API, API, управляемые гипертекстом, предлагают альтернативную точку зрения, которая подчеркивает мощь гиперссылок. Встраивая гиперссылки в ответы API, эти API обеспечивают динамическую навигацию и обнаружение, улучшая возможность обнаружения, гибкость и общее взаимодействие с клиентом.

API-интерфейсы на основе гипертекста позволяют клиентам полагаться на рекомендации, предоставляемые API, уменьшая потребность в жестко закодированных URL-адресах и предопределенных навигационных путях. Это способствует слабой связи, упрощает разработку клиента и упрощает развитие как клиентских, так и серверных компонентов.

Итак, в следующий раз, когда вы будете разрабатывать RESTful API, рассмотрите потенциал API, управляемых гипертекстом, и используйте возможности гиперссылок. Пусть ваш API станет гипермедиа-документом, который поможет клиентам в их путешествии и откроет совершенно новый уровень гибкости и адаптируемости.

Ссылка



https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven