Всем привет!
То, что написано ниже относится к разряду "так делать не надо", однако, если вы считаете иначе — интересно будет услышать ваше мнение на этот счёт )
Наверное, многие из нас делали REST API, либо пользовались чьим-то готовым. Разберём в статье "невероятные" трюки, которые помогут сделать ваше API на голову выше, чем у других.
Белый пояс
Все значения в json — строка и не иначе!
Ну что ж, возьмём простейший объект:
{
"stringValue" : "value",
"intValue": 123
}
Вот к чему 123 тут задавать числом, зачем подобная путаница? Пусть будет строкой, десериализатор разберётся:
{
"stringValue" : "value",
"intValue": "123"
}
Гораздо лучше, не так ли? Хм… А что если у нас объект в качестве значения свойства?
{
"stringValue" : "value",
"intValue": "123",
"complexValue": {
"key": "value"
}
}
Мда… Непорядок! Надо сделать по-нормальному:
{
"stringValue" : "value",
"intValue": "123",
"complexValue": "{
\"key\": \"value\"
}"
}
Что? Там ещё одно вложенное свойство? Ну, так в чем проблема? Рецепт есть уже, всё продумано!
{
"stringValue" : "value",
"intValue": "123",
"complexValue": "{
\"key\": \"value\",
\"anotherComplexValue\": {
\"superKey\": \"megaValue\"
}
}"
}
Вот, везде строка! Не надо заморачиваться с типами! Попарсил строчки и будь здоров!… Что? Библиотека не парсит как надо? Ну, так бери нормальную, которая всё правильно сделает. complexValue как строка воспринимается? Ну, это вообще ерунда, очевидно, что там объект, просто грамотно обёрнутый в строку.
"Key": Value — это скучно, да и на сеть нагрузка большая...
Если в объекте 2-3 свойства, зачем городить сложный объект? Есть хорошее решение:
[
25000,
"Петька",
{
"key1": "value1",
"key2": "value2"
}
]
Супер! Надо Петькину зарплату вытащить? Так бери первое значение! Как Петьку зовут? Второе. Так, а с третьим то непорядок!
[
25000,
"Петька",
"{
\"key1\": \"value1\",
\"key2\": \"value2\"
}"
]
Во! Теперь по уму! А нет, надо же нагрузку снизить на сеть, у нас ведь 5 запросов в секунду:
[
25000,
"Петька",
[
"value1",
"value2"
]
]
Просто супер! Вот бы весь json такой был, цены бы ему не было!
Желтый пояс
Порядок не важен
Если проблемка с последним примером: все значения — строки, помнишь?
[
"Петька",
"[
\"value1\",
\"value2\"
]",
"25000"
]
Что случилось? Зарплата 3-им значением теперь стала? Ну, да, возможно, но так даже лучше. А какая разница? Там ведь значение 25000, понятно же, что число. Сделать числом? Зачем? Все значения — только строки, запомни!
Хранимые процедуры. Ммм… Лакомство
Давай что-нибудь с этим джейсоном полезное сделаем. Например, универсальный исполнитель запросов сделаем, без него любой бэкенд не бэкенд. Берём объект:
{
"queryType": "select",
"table": "lyudi",
"where": "name = Витька AND zarplata > 15000"
}
и в хранимую процедуру его! Она сама разберётся и запрос твой оптимизирует! Где такую взять? А вот сделал добрый человек, пользуйся на здоровье, да добрым словом поминай)
Супер, да?
Не надо спрашивать как это под капотом работает, штука огонь!
Хотя… Постой! Можно же лучше сделать:
{
"query": "select * from lyudi where name = Витька AND zarplata > 15000"
}
Красота да и только! Что? Обычный запрос проще сделать? А кто права на это даст? Вот есть хранимая процедура для универсального выполнения запросов, права даём только на неё и ей одной родимой и пользуемся. ORM? Это что за база такая? Нет-нет. MSSQL и точка.
Красный пояс
Всё переводим на "хранимки"! Ням-ням
Вот может вопрос возникнуть: при чем тут API и хранимые процедуры? Всё очевидно: избавляемся от накладных расходов! Вызвал хэпэшку и вуаля! Поэтому никакого rest'а не надо. Смысл такой: из хранимой процедуры возвращаем несколько курсоров, по ним проходимся и всё готово! И быстро и красиво!
Простите, люди добрые, под рукой примера не было, столь он "идеален", что с наскоку не воспроизведу, но ежели сильно нужно, то просьбам вниму, добавлю примерчик)
Ну, а ежели партнёры со сторонних компаний захотят api использовать так vpn можно сделать, пускай тоже по уму делают: хранимые процедуры используют.
Коричневый пояс
Не надо насчёт коричнего цвета что-то не то думать, это почти чёрный! Высокий уровень то-есть!
JSON произвольной структуры
Если с тех. заданием есть проблемы и заказчик не знает до конца чего он хочет, есть отличный метод! Для данных, о которых пока мало-что знаем заготовим объект произвольной структуры:
{}
Вот так он выглядит на начальном этапе:
{
"key1": "value1",
"key2": 2
}
потом свойства добавятся:
{
"key1": "value1",
"key2": 2,
"key3": {
"123": 456
}
}
но ничего страшного, возможно что вообще всё поменяется:
{
"objectAsArray": ["Vasya", 123, 456, "Piter"]
}
Вот и объект красивый получился! Конфетка просто!
Хранение произвольных данных
Тут вообще проблем нет! Произвольный JSON пишем в базу: для этого заводим столбец с типом VARCHAR(MAX). Всё гениальное просто!
Оптимизация и ничего кроме!
Вот был раньше формат dbf, отчего про него забыли нынче? Применим!
{
"data": "Vasya 123 456 Piter "
}
10 символов для имени, 5 для номера квартиры, 5 для номер дома, 20 для города. Универсально, красиво! Да, иногда символы лишние, но зато какая структура красивая!
Чёрный пояс
Быть ближе к железу!
Строка — это что? Массив байтов, ну, так и давайте следовать определению!
{
"data": [56, 61, 73, 79, 61, 20, 20, 20, 20, 20, 31, 32, 33, 20, 20, 34, 35, 36, 20, 20, 50, 69, 74, 65, 72, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
}
Чуть не забыл! Значения должны быть строкой:
{
"data": "[56, 61, 73, 79, 61, 20, 20, 20, 20, 20, 31, 32, 33, 20, 20, 34, 35, 36, 20, 20, 50, 69, 74, 65, 72, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20]"
}
И универсально, и красиво!
P.S. Не столь "идеальный" P.S. как всё написанное выше...
Если вам показалось, что автор утрирует и выдумывает, то… Автор хотел бы, чтобы так оно и было. Однако, сталкиваться приходилось с каждым из этих случаев. Давайте уважать друг друга и делать добро, а не какую-то ерунду) Спасибо за внимание, надеюсь, местами было не только грустно, но и весело!