Лучшая практика GraphQL для редактирования полей, требующих авторизации - PullRequest
0 голосов
/ 03 мая 2020

Рассмотрим тип User с полем email, которое для определенных «анонимных» пользователей должно быть доступно только при условии правильной авторизации запроса. Другим пользователям хорошо, если их электронная почта публично отображается.

type User {
  name: String!
  "Anonymous users have the email only accessible to admins"
  email: String!
}

Каковы плюсы и минусы этих двух подходов к обработке этого поля в распознавателе email для анонимных пользователей?

  1. throw если запрос не авторизован. В этом случае
    • email необходимо объявить как nullable String вместо String!, , иначе весь запрос выдаст ошибку .
    • Клиент может хотите сопоставить с errors с data. Поскольку неанонимные пользователи будут иметь доступ к своей электронной почте без авторизации, errors и data могут иметь различное количество элементов, поэтому такое сопоставление кажется невозможным , по крайней мере с сервером apollo, который не возвращать что-либо в каждом элементе errors, которое указывало бы, к какому user элементу оно относится.
    • email будет вводить в заблуждение null для анонимных пользователей, путая ситуацию с ситуацией, в которой электронное письмо никогда не добавлялось на первом месте. Помните, что email должно быть String, а не String!, поэтому электронное письмо null является разумным.
    • В ответе имеется четкий массив errors, поэтому это выглядит как " правильный "подход?
  2. вернуть письмо в отредактированной форме, например [NOT AUTHORIZED TO ACCESS THIS USER'S EMAIL].
    • Это позволяет сохранить целостность объектов с явными ошибками для чувствительных электронных писем, вместо того, чтобы вводить в заблуждение "нулевые" электронные письма.
    • email может остаться ненулевым
    • Не нужно пытаться для сопоставления errors с data.
    • В ответе нет явного массива errors, так что это похоже на взлом.

Обратите внимание, что для массивов возврат формы REDACTED не является опцией, поскольку запрос может запросить поле в массиве (например, { anonUsers { email } }). Единственный вариант - вернуть [] (напрямую или throw ing).

Я что-то упустил? Есть ли предварительная работа над этим топи c? Как я могу принять решение?

1 Ответ

1 голос
/ 09 мая 2020

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

interface UserInformation {
  id: ID!
  userName: String
  firstName: String!
  lastName: String
  avatarImage: String
  city: String
  ...
}

Тогда у вас будет две отдельные реализации:

type UserPublic implements UserInformation {
  id: ID!
  userName: String
  firstName: String!
  lastName: String
  avatarImage: String
  ...
}
type UserPrivate implements UserInformation {
  id: ID!
  userName: String
  firstName: String!
  lastName: String
  avatarImage: String
  friends: [UserInformation!]
  pendingFriends: [UserInformation!]
  phone: String
  email: String
  birthday: DateTime
  ...
}

Все остальные ваши запросы и типы используют базовый тип интерфейса UserInformation при отображении Пользователей. Тогда ваш сервер graphql просто возвращает либо UserPublic, либо UserPrivate в зависимости от того, какой тип доступа имеет пользователь.

На стороне клиента вы запрашиваете его следующим образом:

query SomeQuery {
  getSomeData {
    user {
      id
      userName
      firstName
      lastName
      avatarImage
      ...on UserPrivate {
        email
        phone
      }
      ...

Вы Затем можно проверить на стороне клиента, был ли возвращенный тип поля (__typename) UserPublic или UserPrivate и действовать соответственно.

...