Так чи потрібен rest для веб-додатків
Що таке REST?

Звичайне середньостатистичне веб-додаток обходиться двома типами запитів: GET і POST, для отримання і відповідно відправки даних. Але RESTful архітектура має на увазі використовувати весь спектр запитів: GET - отримати дані, POST - відправити нові дані, PUT - відправити відредаговані дані, DELETE - видалити дані. Є ще PATCH, який за своєю ідеї повторює PUT, відмінності лише в тому, що PUT передбачає замінити повністю запис, а PATCH тільки частково оновити дані. Що цікаво, думки про використання POST і PUT розходяться. Англомовні розробники вважають за краще використовувати саме PUT для додавання нових даних, а POST для редагування.
Використання REST на прикладі GML
Для початку нам потрібно визначитися з ресурсами, з якими може взаємодіяти користувач. На GML у мене вийшло: лінки (посилання на веб-ресурси), збірники (контейнери для лінків), користувачі і теги. Це чотири основних одиниці, з якими відбувається робота.
Позначимо кореневої домен як gml.link/
У нас виходять такі запити на отримання даних:
- GET gml.link/links/ - отримати весь список лінків
- GET gml.link/links/125 - отримати сто двадцять п'ятий лінк
- GET gml.link/collections/ - отримати список всіх збірників
- GET gml.link/collection/34 - отримати список лінків тридцять четвертого збірника
- GET gml.link/tags/ - отримати список всіх тегів
- GET gml.link/tags/animal - отримати список лінків з тегом 'animal' (для тегів в якості ідентифікатора виступає його назву, а не номер.)
Запити на додавання даних (в круглих дужках вказані дані передаються в тілі запиту)
- POST gml.link/users/ (username: 'Alex', password: 'sdf7665 $ 6', email: '[email protected]') - додати нового користувача
- POST gml.link/users/23 (username: 'Alex', password: 'sdf7665 $ 6', email: '[email protected]') - в даному випадку повернеться помилка, так як ми вказали в запиті ідентифікатор конкретного користувача
- POST gml.link/collections/ (title: 'Нова колекція', 'type': 'private') - створить новий приватний збірник
Запити на редагування
- PUT gml.link/collections/ (title: 'Змінена назва збірки') - поверне помилку, так як не вказано ідентифікатор збірки
- PUT gml.link/collections/12 (title: 'Змінена назва збірки') - змінить назву у дванадцятого збірника
- PUT gml.link/links/117 (title: 'Інша назва линка') - змінить назву у сто сімнадцятого линка
Запити на видалення
- DELETE gml.link/collection/32 - видалить тридцять другому збірник
- DELETE gml.link/links/43 - видалить сорок третій лінк

Зовсім трохи про технічну реалізації
(Увага, прочитавши цю частину, ваше життя може назавжди змінитися)
Так як ми не на Хабрахабр, тому технічну реалізацію я торкнуся умовно.
Весь процес обробки запиту ділиться на кілька етапів:
- Визначення ресурсу, до якого направлено запит (links, collections, users і tags, і id ресурсу)
- Визначення дії з типу запиту (отримання, додавання, редагування та видалення)
- Збір додаткових параметрів із запиту (для додавання \ редагування - це безпосередньо дані ресурсу, для отримання - це різні фільтри)
У чому переваги даного архітектурного підходу?
Застосувавши REST на своєму проекті, для себе я відзначив наступне:
Що далі? (в загальному)
Як я вже говорив, статті буду писати по мірі реалізації тієї чи іншої частини сервісу. На даний момент вже готова реєстрація / аутентифікація, повністю підтримана REST архітектура, реалізована "lazy load" подгрузка лінків, додавання / створення збірки.
-- Збереження стану сторінки через HTML5 History API (як бонус)
Знову ж таки, дуже опосередковане відношення до REST API
-- Ні плутанини з додатковою передачею параметрів в запитах і обробкою їх на сервері
Якраз і починається плутанина. Що передаємо через GET параметри, щось через POST в один і той же обробник.
-- Прозора логіка клієнтської частини програми
-- У разі потреби легко надати RESTful API для сторонніх додатків
А інші протоколи не пропонують цієї можливості?
У REST є багато невизначеностей і через це у кожного з'являються свої реалізації, які вони вважають еталонними.
Немає більш менш чіткої специфікації. Наприклад відповідь про помилку:
1. HTTP код
2. Завжди 200, інформація про помилку у відповіді
3. 1 і 2 варіант
Формат відповіді. Припустимо викликаємо метод отримання користувачів:
1. [
2.
3.
Хтось як любить, так і робить. Великий мінус якщо доводиться інтегруватися з декількома сервісами.
Веселощі починається, коли потреби виходять за рамки простого додавання, отримання списку, видалення (типовий CRUD), тобто виходимо за рамки /: collection /: id
Ось є якась сущьность, у який є властивості і методи. Як ці дії виконати?
1. POST /: collection /: id / on
2. Передавати "дія" в тілі POST
3. Чи взагалі використовувати, PUT, PATCH
Невелика проблема виникає, коли йде кросбраузерності запит (CORS) до нашого API. На кожен url (/: collection /: id) буде слати попередній OPTIONS запит, додаткові затримки.
Додали GET / PATCH / DELETE обробник /: collection /: id. І хочемо в браузерному додатку использвать JSONP, щоб позбутися від політик CORS. Доведеться додавати ще один обробник (3-в-1), для підтримки JSONP (він адже тільки GET).
Немає стандрат інструментів для опису сервісу, за типом WSDL. Точніше більш-менш широковживаних.
При типовому REST API, документація і параметри описуються вручну. Документація буде постійно відставати.