Pull to refresh

Быстрый старт для ExtJS back-end

Reading time5 min
Views14K

Проблема взаимопонимания


Представьте себе ситуацию: вы — фрилансер и работаете с 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
  1. Отправка GET запроса (в БД на сервер должен быть хотя бы один айтем)
  2. Отправка POST запроса содержащего все или необходимые данные. В ответе должна придти информация по новому айтему.
  3. Отправка GET запроса и проверка наличия созданного в пункте 2 айтема
  4. Отправка PUT запроса для изменения айтема, созданного в пункте 2 и полученного среди прочих в списке в пункте 3. В ответе должна придти информация по изменённому айтему
  5. Отправка GET запроса и проверка изменения созданного в пункте 4 айтема
  6. Отправка DELETE запроса для удаления айтема, созданного в пункте 2. В ответ приходит подтверждение.
  7. Отправка GET запроса и проверка отсутствия созданного в пункте 2 айтема


Заключение


Возможно кому то данный документ будет бесполезен, а кому то, как и мне, сохранит немного ценного времени.
Tags:
Hubs:
+2
Comments16

Articles

Change theme settings