
Проблема взаимопонимания
Представьте себе ситуацию: вы — фрилансер и работаете с Ext. С вами удалённо работает один (или несколько) разработчиков back-end. Работа идёт быстро и гладко. Но вот вот случилось так, что разработчик серверной части сменился. Если у нового коллеги есть опыт взаимодействия с Ext — всё замечательно. Но вот если человек впервые будет писать back-end для Ext или впервые будет писать для веба (такое тоже случается), то вам будет необходимо найти общий язык.
И вот тут могут начаться проблемы…
Придётся тратить время на простое объяснение протокола, объяснения как должен реагировать сервер на те или иные запросы. Чтобы избежать этого, я подготовил документ, описывающий все (ну или почти все нюансы стандартного для Ext протокола). Этот документ и представлен под катом.
Решение проблемы взаимопонимания
ExtJs на полную использует возможности REST архитектуры взаимодействия. Что это и с чем едят уже писали на хабре:
REST vs SOAP. Часть 1. Почувствуйте разницу
Дао Вебсервиса. (Или да хватит же изобретать велосипеды!)
Автору первого топика (Artiom1988) — огромное человеческое спасибо за таблицу, она сэкономила мне огромное количество времени при общении с разработчиками. И её (с небольшими изменениями) я украл для своего документа
Стандартные HTTP операции
| URL | GET | POST | PUT | DELETE |
| example.com/ticket | Получаем список всех билетов | Создаём новый билет | Обновляем список билетов | Удаляем все билеты |
| example.com/ticket/15 (где 15 — id билета) | Получаем информацию по конкретному билету | -- | Изменяем билет | Удаляем конкретный билет |
Запросы должны работа в случаях, когда URL содержит финальный слеш (www.exam.com/ticket/) и когда слеш отсутствует (www.exam.com/ticket)
У каждого объекта (билета, юзера и т.д.) есть поле id — уникальный идентификатор в виде целочисленого значения.
Формат сообщений
Все сообщения передаются в валидном JSON.
Далее массивом будем называть конструкции вида:
[1,2,3,4,"строка",true, false, "34"]
а объектом конструкции вида
{"param1" : "value1", "param2" : true, "param3": 45}
обратите внимание, что имена параметров всегда строки (в двойных кавычках), значения параметров могут быть строками, числами и булевыми (true и false)
Полями будем называть имена параметров, в объекте выше есть поля param1 и param2
Объекты могут включать массивы, а массивы объекты, например
{ "success": true, "items" : [ { "name": "Vasya" }, { "name" : "Sveta" }] }
Формат запросов клиента
POST и PUT
Содержит один параметр items, который представляет из себя объект
{"name":"123","id":0,"region_id":2,"region_name":""}
GET
При запросе списков может сдержать стандартные параметры:
start — номер записи с которой начинается ответ
limit — максимальное количество возвращаемых записей
filter — массив, содержащий объеты вида
{"property":"name","value":"Вася"}
т.е. GET запрос
/users?start=40&limit=20&filter=[{"property":"name","value":"Вася"}](запрос естественно uri кодирован) должен вернуть 20 пользователей с именем Вася, пропустив первые 40 из БД.
Хорошей практикой использовать для полнотекстовой фильтрации фильтры с именами как у искомого поля + строка "_like". Т.е. фильтр
найдёт и Василиев и Василис. Пораметры, имеющие полнотекстовый поиск, естественно стоит оговаривать.{"property":"name_like","value":"Вас"}
Формат ответов сервера
Ответ всегда представляет из себя объект.
Обязательно должно быть поле success, которое может принимать булевы значения.
Ответы на GET запросы
Если запрашивается список предметов, то в ответе должно быть поле total, представляющее из себя целое число, показывающее общее количество строк в БД для этого контроллера (т.е. если мы указали параметры filter и limit и получили несколько записей, то в total всё равно указывается обзее количество записей).
Если запрашивается конкретный предмет (
exmple.org/users/5), то поле total не ставится.Сами данные находятся в поле items, которое представляет из себя массив, содержащий объекты-данные.
{ "items":[{ "region_id":2, "name":"Moscow", "id":25 },{ "region_id":1, "name":"Piter", "id":18 }], "success":true, "total":2 }
Если был запрошен один объект, то массив не используется
{ "items":{ "region_id":2, "name":"Moscow", "id":25 },{ "region_id":1, "name":"Piter", "id":18 }, "success":true }
Ответы на DELETE запросы
— Этого достаточно{"success":true}
Ответы на POST и PUT запросы
Аналогичны ответу на GET запрос, при запросе конкретного объекта, только должны возвращать уже изменённые данные.
Ошибки
В случае ошибок поле success равно false, так же добавляется поле errors — массив строк с описанием ошибок
{"errors":["Object not found"],"success":false}
Именование данных
В случае, если объекту нужно ссылаться на другой объект, используется параметр с приставкой _id, т.е. если сервер возвращает объект-город, а город находится в регионе, то ответ может быть такого вида:
{"region_id":2,"name":"Moscow","id":25}
В случае необходимости может быть добавлено поле region_name содержащее имя региона (а в БД работающее как поле, которое кэшируется в таблице городов).
Когда один объект содержит много и необходимо получить вложеную иерархию используется поле-массив с именем во множественном числе, т.е. если запрашивается регион, к которому прикреплены несколько городов, то ответ может быть таким:
{ "id":2, "name":"Central", "cities" : [{ "name": "Moscow", "id":2 },{ "name":"New York", "id":3 }] }
Методика тестирования бэкенда
Для тестирования можно использовать замечательное расширение Google Chrome
- Отправка GET запроса (в БД на сервер должен быть хотя бы один айтем)
- Отправка POST запроса содержащего все или необходимые данные. В ответе должна придти информация по новому айтему.
- Отправка GET запроса и проверка наличия созданного в пункте 2 айтема
- Отправка PUT запроса для изменения айтема, созданного в пункте 2 и полученного среди прочих в списке в пункте 3. В ответе должна придти информация по изменённому айтему
- Отправка GET запроса и проверка изменения созданного в пункте 4 айтема
- Отправка DELETE запроса для удаления айтема, созданного в пункте 2. В ответ приходит подтверждение.
- Отправка GET запроса и проверка отсутствия созданного в пункте 2 айтема
Заключение
Возможно кому то данный документ будет бесполезен, а кому то, как и мне, сохранит немного ценного времени.
