Как стать автором
Обновить

Комментарии 11

Городить отдельный тип со своей ошибкой для такого простого поля, как email, кажется оверхедом, ведь это всего лишь строка.

Какая-то тут недосказанность в истории с PersonItem и PersonFullItem. У вас же наверняка есть кейсы, когда у объекта Х полей и лишь несколько из них появляются всегда. Получается, что все же придется идти на оверхед и заменять примитивные типы алгебраическими.

Не очень понял с чего вывод про наверняка) И все таки, что значит "появляются всегда". Если речь о том, что есть место в приложении, где мы показываем маленькую часть объекта - так GraphQL и нужен для этого, клиент просит только эти поля.

В реальности у нас все устроено как я описал тут. Кейс про email я выбрал для наглядности, основная проблема у нас была с вакансиями, которые показываем в откликах кандидата (их могу видеть все, но в саму вакансию перейти не могут). Вероятно нет сложных кейсов потому, что это все таки кабинет в рамках компании, а не сайт hh.ru, где есть поконтактный доступ (часть полей может быть скрыто, но и это не проблема, их то как раз можно целиком выделять в алгебраический тип блоком - например ContactsItem и ContactsError)

У нас же у компании либо куплен доступ ко всему кабинету, либо нет. А для отдельных ролей могут быть просто видны названия чужих вакансий, или наоборот не видны чужие кандидаты (если откроют по прямой ссылке такого)

можно целиком выделять в алгебраический тип блоком - например ContactsItem и ContactsError

Список полей предлагается делать или как? Можно пример?

Может не понял про список полей, но у кандидата будет поле contacts типа Contacts, как-то так:

union Contacts = ContactsItem | ContactsError

type ContactsItem {
  items: Contact[]
}

type Contact {
  type: ContactType #email,phone,...
  value: String
}

type ContactsError {
  errorType: ContactsErrorType 
  # тут тип, например "Неоплачен доступ", "Кандидат скрыл данные" и т.д
}

Да, могут быть разные блоки, еще например ФИО и день рождения, их можно целиком еще в один объект. Если прям хочется динамические блоки в зависимости от ролей, и динамически включать и выключать, то тут конечно придется уже наверное более синтетические списки этих самых полей в дженерном виде.

Пример достаточно топорный, там можно накручивать.. Могут быть полные и не полные контакты (будет три состояния, вообще недоступны, виден только часть, видны все). + со списками еще логика такая - выдаем то, что доступно тебе (когда запрашиваешь "мои вакансии", тут все как в обычном REST API)

  1. Убираем обязательность из полей ответа. Клиент сам может решить, что ему запрашивать.

  2. Пишем ошибку доступа в стандартный блок ошибок.

И не нужно заморачиваться с юнионами PersonItem/PersonError.

вы путаете обязательность заполнения и ответа)

NonNull (или восклицательный знак) означает не обязательность ответа, а то, Что если вы его запросили, оно точно не null. И избавляться от этих пометок это самое последнее что хочется делать. Клиенту хочется знать что всегда заполнено, а на что ему надо обрабатывать null-ы
GraphQL на то он и нужен, что никакой обязательности ответов нет, запрашивай что хочешь (иначе смысл?)

ну и соответственно тот самый кейс - запросили email, выдали вам null

как вам понять недоступен он или не заполнен? В массив errors писать можно об этом, но это неудобно (нет строгой типизации в ошибках, просто набор полей, перечисление типов ошибок). Получается что контракт по ошибкам хранится где-то в другом месте, а о сущностях - в схеме. Хочется чтобы было единое место знаний - схема.

Отчасти с вами согласен, в массиве ошибок ошибки пишутся в произвольном формате, который схемой не задаётся. На нашем проекте о нём мы просто договорились. На бэке он генерится

Однако, если в email пришёл null, то это и есть null, т.к. в противном случае пришла бы ошибка.

Не хватает пары примеров, какие конкретно ваши проблемы решил переезд на GraphQL

Хороший вопрос, но о причинах перехода (они же примеры, и они же в итоге и дали профит) описано в другой нашей статье https://habr.com/ru/company/hh/blog/677972/

Хорошая статья! Буду ждать следующий выпуск :half_troll:

Зарегистрируйтесь на Хабре, чтобы оставить комментарий