Можно ли иметь разные типы для одного и того же поля между схемой Prisma GraphQL и моделью данных?

Я новичок в Prisma / GraphQL. Я пишу простое приложение ToDo и использую Apollo Server 2 и Prisma GraphQL в качестве бэкэнда. Я хочу преобразовать свое поле createdAt из модели данных во что-то более удобное для внешнего интерфейса, например строку даты в формате UTC. Моя мысль заключалась в том, чтобы преобразовать сохраненное значение, которое является DateTime.

Мой datamodel.prisma имеет следующее для типа ToDo

type ToDo {
id: ID! @id
added: DateTime! @createdAt
body: String!
title: String
user: User!
completed: Boolean! @default(value: false)

}

Поле added - это DataTime. Но в моем schema.js я перечисляю это поле как строку

 type ToDo {
    id: ID!
    title: String,
    added: String!
    body: String!
    user: User!
    completed: Boolean!

  }

и я конвертирую его в свой резолвер

 ToDo: {
    added: async (parent, args) => {
      const d = new Date(parent.added)
      return d.toUTCString()
    }

Это нормально? То есть иметь разные типы для одного и того же поля в datamodel и schema? Кажется, это работает нормально, но я не знал, открываю ли я себя для проблем в будущем, следуя этой технике в других обстоятельствах.

Если это так, то мне было любопытно, почему доступ к parent.added в ToDo.added резолвере не запускает какой-то «бесконечный цикл», то есть когда вы обращаетесь к полю parent.added, он не смотрит на преобразователь для разрешить это поле, которое обращается к полю parent.added и так далее. (Я думаю, это достаточно умно, чтобы этого не делать?)


person Cerulean    schedule 02.05.2019    source источник


Ответы (1)


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

Ваша первая модель (datamodel.prisma) использует расширенный синтаксис и директивы Prisma для точного описания ваших данных и используется слоем Prisma, тогда как вторая модель использует стандартный синтаксис GraphQL для реализации того же объекта, что и действительный стандартный тип GraphQL, и используется вашим собственным сервером.

Фактически, если вы посмотрите на него, вы увидите, что тип DateTime, используемый Prisma, на самом деле является String, но, вероятно, он используется Prisma для проверки форматов даты и времени и т. Д., Поэтому между обеими моделями нет фундаментальных расхождений. Но даже если возникнет несоответствие, это будет зависеть от вас, поскольку вы можете использовать резолверы для переопределения данных, полученных от Prisma, перед их возвратом из собственной серверной части.

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

Что касается вашего вопроса о преобразователе, parent в этом контексте будет содержать объект, возвращенный родительским преобразователем. Представьте, что у вас есть getTodo запрос на уровне Query корня, возвращающий единственный элемент типа ToDo. Предположим, вы разрешили это действие Prisma по умолчанию для получения одного ToDo. Согласно вашему datamodel.prisma файлу, этот запрос будет преобразован в объект, имеющий свойство added (которое будет существовать в вашей БД как поле createdAt, как указано в директиве @createdAt Prisma). Таким образом, parent.added будет содержать это значение.

Ваш преобразователь added преобразует этот исходный фрагмент данных, превращая его в фактический объект Date, а затем форматируя его в строку UTC, которая соответствует вашему schema.js файлу, где поле added имеет тип String!.

person Thomas Hennes    schedule 08.05.2019