Художественный архитектурный дизайн 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-адреса или предопределенные пути навигации.
Теперь, прежде чем вы продолжите чтение, вам нужно установить несколько вещей, чтобы начать тестирование кодов в каждом примере.
- Убедитесь, что на вашем компьютере установлены Node.js и npm. Вы можете скачать и установить Node.js с официального сайта: https://nodejs.org или NPM с https://docs.npmjs.com/downloading-and-installing-node-js-and-npm.
- Создайте новый каталог для вашего проекта.
- Откройте терминал или командную строку и перейдите в каталог проекта.
- Скопируйте пример кода в новый файл и сохраните его с расширением .js, например ecommerce.js. В терминале или командной строке установите необходимые зависимости, выполнив следующую команду:
экспресс-установка npm
5. После завершения установки запустите сервер, выполнив следующую команду:
узел электронной коммерции.js
6. Вы должны увидеть сообщение о том, что сервер работает на определенном порту (в данном случае 3000).
7. Откройте веб-браузер и перейдите по адресу http://localhost:3000/products, чтобы проверить конечную точку списка продуктов.
Вы должны увидеть ответ JSON, содержащий информацию о доступных продуктах.
8. Попробуйте получить доступ к другим конечным точкам, таким как /cart, /cart/checkout и /cart/payment_infoдля тестирования различных функций платформы электронной коммерции.
Не стесняйтесь исследовать код и вносить изменения в соответствии с вашими потребностями. Вы можете добавлять новые маршруты, реализовывать функции добавления/удаления товаров из корзины или интегрироваться с базой данных для сохранения данных.
Обратите внимание, что это базовый пример для целей тестирования. В реальном сценарии вам нужно будет рассмотреть дополнительные меры безопасности, обрабатывать операции с базой данных и обрабатывать аутентификацию/авторизацию пользователей.
Переосмысление взаимодействия с API
- Представьте себе 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