Comments 11
Спасибо огромное за статью!

Работаю над похожей темой, но на typescript, без реакта и на swagger-е. Пожалуй пощупаю и JSON API, Ваш опыт заинтересовал. Подскажите пожалуйста, я бегло пробежался по документации но не увидел — как дела у JSON API с валидацией данных? Есть механизмы?

Спасибо за теплые слова!


Я не уверен, что на 100% правильно понял вопрос, но постараюсь ответить. JSON API не является "движком", на котором вы реализуете API. Это лишь набор правил, которые описывают:


  • как конвертировать данные в формат JSON API
  • как должны выглядеть URI веб-сервисов и формат CRUD запросов
  • формат предоставления URL, чтобы клиент мог автоматически распознать pagination объекты и знать, как запросить следующую порцию.

То есть, мы имеем дело исключительно с форматом представления данных и форматом методов работы с ними, — некоторая надстройка над традиционным JSON'ом, которая ничего не знает и не должна знать о вашей бизнес-логике, но содержит мета-информацию (типы объектов, ссылки для pagination и т.п.).


Конвертацию из JSON API в объекты на стороне клиента делает моя библиотека (тут валидация, вероятно, не нужна), на стороне сервера делает какая-нибудь другая библиотека, которая будет у каждого стека своя. Далее уже вы валидируете объекты после конвертации как обычно. Если вам прислали "кривой" запрос, то ловите исключение парсера в контроллере и возвращаете ту ошибку, которая вам кажется логичнее.

Не хватает более подробного объяснения, что не так с Normalizr/Denormalizr, который сейчас считается стандартным решением

Да, справедливо


Для работы с normalizr необходимо явно указать Scheme ваших данных, что излишне для работы с JSON API (я имею в виду именно стандарт http://jsonapi.org, а не произвольный API в формате JSON), так как сам документ содержит в себе все необходимые метаданные. Normalizr просто не подходит для работы с JSON API. Вероятно, их можно интегрировать, но трудозатраты на это едва ли оправданы. Также normalizr заточен на работу с данными, в то время, как JSON API функционально богаче и может содержать мета-данные и ссылки для pagination, sorting, filtering.

А еще из листинга стоит убрать файлы package.json Полезной информации там нет, без них код читать будет проще

return fetch(fullUrl, options)
    .then(response => response.json()
      .then((json) => {

Вот тут по спеке Promise-ов можно избавиться от вложенности:


You can pass a lambda to then and if it returns a promise, an equivalent Promise will be exposed to the subsequent then in the method chain

return fetch(fullUrl, options)
    .then(response => response.json())
    .then((json) => {

А ещё можно вообще избавиться от Promise-ов и начать использовать RxJS с React-ом:
https://habrahabr.ru/post/309226/

Спасибо за комментарий, этот код я скопи-пастил с real-world-example Дэна Абрамова.


Мне нужно было проиллюстрировать, что json-api-normalizer позволяет интегрировать JSON API и redux одной строкой, что я и сделал :) Так что вполне допускаю, что именно этот кусок можно было написать лучше

Исходя из моего опыта правил JSONAPI недостаточно обычно и постоянно возникают вопросы «А как реализовать то или то»и никакая библиотека не покрывает нужны целиком. Например, фильтрация и сортировка в JSONAPI не описана. Пишите как хотите. И все библиотеки реализовывают их по разному. В redux я использовал redux-json-api, но его пришлось выкинуть так как количество нереализованных, но нужных фич очень большой. Простите, но сейчас 2017 год и не JSONAPI, который был еще 6 лет назад набирает популярность, а нормальные решения для API. Попробуйте например Graphql. Вы просто не захотите больше никогда видеть JSONAPI после него.
Вкратце плюсы Grapql например: валидация из коробки, чистый код, легкое взаимодействие с redux, нормальное описание сущностей, вебморда чтоб тестить все запросы.
Там в одном из комментариев также писали, что используют Swagger. Тот же самый ответ. Зачем использовать Swagger в 2017? Используйте решения у которых все запросы отображаются по умолчанию в вебморде как только вы их создаете, а не их необходимо описывать. Неужели вам недостаточно что вы пишите код и вы еще хотите описывать каким то DSL какие данные кормить запросам?

JSON API — это формат представления данных, настройка над JSON. Именно поэтому я отказался от redux-json-api и написал свое решение — я сам хочу управлять стейтом, как мне удобно для своего проекта, а не городить костыли и redux middleware, чтобы реализовывать бизнес-логику.


GraphQL — это решение "под ключ", их, наверное, не очень корректно сравнивать. Я пробовал использовать GraphQL в рамках Proof of Concept и для нужд моего проекта он подошел плохо, по крайней мере, он создавал больше проблем, чем их решал. Я бы мог поспорить с каждым из ваших аргументов, которые вы описали, как плюсы, кроме вебморды, чтобы тестить запросы. Количество кода он не уменьшает — вы его просто переносите на клиент в виде Query, объем трафика вы ощутимо снижаете только при работе с огромными объектами с 200 полями, и, если вы не фейсбук, то у вас их скорее всего не будет. При этом вы ломаете транзакционность, так как тащите объект в store по частям и не факт, что полученный объект будет соответствовать тому, что у вас в бекенде. Хотите сохранить транзакционность? Ломаете кеш. Главный плюс GraphQL следующий — вы стандартизируете разработку API и взаимодействие с ним, если у вас большая команда, то вы снижаете свои издержки на коммуникации и "подумать". Но это не killer feature.

тоже пытался перейти на GraphQL, но для этого надо переписать половину проекта, а даже если начинать с ним новый проект — надо менять подход в голове (а я еще не отошел от смены подхода после перехода на сам react :D)

Only those users with full accounts are able to leave comments. Log in, please.