В моей модели данных Prisma я начал с такого базового типа пользователя:
type User {
name: String!
email: String! @unique
password: String!
}
Теперь у пользователя может быть две роли: либо кандидат, либо пользователь, связанный с работодателем. Если кандидат, пользователь также должен иметь набор приложений и набор квалификаций, если он связан с работодателем, он должен иметь уровень доступа и ссылку на работодателя.
Во-первых, есть ли способ расширить базовые типы в моделировании данных GraphQL? Если да, то как мне это сделать?
Если нет, я вижу три разных используемых метода, и мне любопытно, каковы плюсы и минусы каждого подхода:
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!
}
Снова два отдельных типа, но с 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!
}
Расширение User, чтобы поля внутри EmployerUser и CandidateUser были необязательными параметрами. Это довольно простой подход, но мне понадобится специальная обработка для обеспечения обязательных полей (например, я не могу отметить, например, работодателя, как требуется, поскольку это поле не будет существовать для кандидата).
type User{
name: String!
email: String! @unique
password: String!
applications: [Application!]!
qualifications: [Qualification!]!
employer: Employer
accessRight: AccessRight
}
Я действительно хочу спросить, есть ли лучший способ решить эту проблему. Я все еще новичок в GraphQL и не лучший разработчик данных для начала, но я бы высоко оценил любое подталкивание в правильном направлении :)
И если у меня нет другого выбора, кроме трех, которые я перечислил, какой из них будет наиболее разумным?


Вы пытаетесь реализовать тип интерфейса:
An Interface is an abstract type that includes a certain set of fields that a type must include to implement the interface.
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 вариантам:
- Storing all data with optional type-specific fields under one type (the interface) in Prisma, and then splitting the data back between the primitive types in the app server.
- Storing the data in each primitive type on Prisma, and stitching things for queries on the app server.
О, теперь я вижу, что Prisma не поддерживает интерфейсы, так что я все еще застрял
@LarsHoldaas Я плохо подумал, что вы задаете простой вопрос GraphQL. (Я только что добавил тег prisma). Типы интерфейсов для проблемы с prisma-graphql обсуждались здесь: выпуск # 83. В этой проблеме должны быть какие-то обходные пути.
В любом случае это был отличный ответ! Я думал, что мой вопрос был общим вопросом GraphQL, пока я не прочитал ваш ответ, а затем обнаружил, что Prisma не поддерживает его, поэтому я сам не пометил его. Я должен помнить об этом для будущих вопросов.
Итак, если и Candidate, и EmployerUser реализуют User, будет ли электронная почта:
String! @uniqueобеспечивать, чтобы этот адрес электронной почты был уникальным как для Candidates, так и для EmployerUser, или только в каждом поле?