Моделирование данных GraphQL - расширенные типы (Prisma) - PullRequest
0 голосов
/ 10 сентября 2018

В моей модели данных Prisma я начал с базового типа пользователя, такого как:

type User {
  name: String!
  email: String! @unique
  password: String!
}

Теперь пользователь может иметь две роли: либо в качестве кандидата, либо в качестве пользователя, связанного с работодателем. Если кандидат, пользователь также должен иметь набор приложений и набор квалификаций, если он связан с работодателем, он должен иметь уровень доступа и ссылку на работодателя.

Прежде всего, есть ли способ расширить базовые типы в моделировании данных GraphQL? Если так, как бы я это сделал?

Если нет, я вижу три разных метода, и мне интересно, каковы плюсы и минусы каждого подхода:

  1. Имеет два отдельных типа CandidateUser и EmployerUser, каждый с полями name, email, password. Я вижу две проблемы с этим подходом: тег @unique на email не надежен, и мне придется написать пользовательскую проверку, чтобы убедиться, что поле уникально для обоих типов; а наличие единственной функции входа в систему, которая принимает электронную почту и извлекает соответствующие данные пользователей, больше не является тривиальным: необходимо выполнить поиск в обеих таблицах.

Как это:

    type CandidateUser {
      name: String!
      email: String! @unique
      password: String!
      applications: [Application!]!
      qualifications: [Qualification!]!
    }
    type EmployerUser{
      name: String!
      email: String! @unique
      password: String!
      employer: Employer!
      accessRight: AccessRight!
    }
  1. Снова два отдельных типа, но с RootUser, содержащим name, email и password, и с CandidateUser и EmployerUser, каждый из которых имеет непосредственную ссылку на RootUser. Это приведет к применению тега @unique в поле электронной почты, но поиск все равно будет нетривиальным.

    type RootUser{
      name: String!
      email: String! @unique
      password: String!
    }
    type CandidateUser {
      rootUser: RootUser!
      applications: [Application!]!
      qualifications: [Qualification!]!
    }
    type EmployerUser{
      rootUser: RootUser!
      employer: Employer!
      accessRight: AccessRight!
    }
    
  2. Расширение User, чтобы поля в EmployerUser и CandidateUser были необязательными параметрами. Это довольно простой подход, но мне понадобится настраиваемая обработка для обеспечения обязательных полей (например, я не могу пометить, например, работодателя, как требуется, так как это поле не существует для кандидата).

    type User{
      name: String!
      email: String! @unique
      password: String!
      applications: [Application!]!
      qualifications: [Qualification!]!
      employer: Employer
      accessRight: AccessRight
    }
    

Я действительно хочу спросить, есть ли лучший способ решить это. Я все еще довольно новичок в GraphQL и не самый лучший разработчик моделей данных для начала, но я очень ценю любое движение в правильном направлении:)

А если у меня нет другого выбора, кроме трех, которые я перечислил, какой из них был бы наиболее целесообразным?

1 Ответ

0 голосов
/ 10 сентября 2018

То, что вы пытаетесь сделать, это реализовать тип интерфейса :

Интерфейс - это абстрактный тип, который включает в себя определенный набор полей, которые тип должен включать вреализовать интерфейс.

interface User {
  name: String!
  email: String! @unique
  password: String!
}

Это означает, что любой тип, который реализует User, должен иметь эти точные поля с этими аргументами и возвращаемыми типами.Так что теперь ваш тип Candidate может реализовывать User:

type Candidate implements User {
  name: String!
  email: String! @unique
  password: String!
  applications: [Application!]!
  qualifications: [Qualification!]!
}

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


Обновление:

С этого моментасейчас вопрос Prisma GraphQL, вы должны знать, что Prisma пока не поддерживает интерфейсы или типы объединения . выпуск # 83 и выпуск # 165 обсуждают оба соответственно как запросы функций.

Однако, есть отличная статья, в которой обсуждаются обходные пути для такого подхода:

Интерфейсы GraphQL (и типы объединений) с Prisma и Yoga

, которые сводятся к 2 вариантам:

  1. Хранение всех данных с необязательными полями, относящимися к типу, под одним типом (интерфейсом) в Prisma, а затем разделение данных между типами примитивов на сервере приложений.
  2. Хранение данных в каждом типе примитивов в Prismaи сшивание вещей для запросов на сервере приложений.
...