简体   繁体   中英

Can one have different types for same field between Prisma GraphQL schema and datamodel?

I'm a newbie to Prisma/GraphQL. I'm writing a simple ToDo app and using Apollo Server 2 and Prisma GraphQL for the backend. I want to convert my createdAt field from the data model to something more usable on the front-end, like a UTC date string. My thought was to convert the stored value, which is a DateTime.

My datamodel.prisma has the following for the ToDo type

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

}

The added field is a DataTime. But in my schema.js I am listing that field as a String

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

  }

and I convert it in my resolver

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

Is this OK to do? That is, have different types for the same field in the datamodel and the schema ? It seems to work OK, but I didn't know if I was opening myself up to trouble down the road, following this technique in other circumstances.

If so, the one thing I was curious about is why accessing parent.added in the ToDo.added resolver doesn't start some kind of 'infinite loop' -- that is, that when you access the parent.added field it doesn't look to the resolver to resolve that field, which accesses the parent.added field, and so on. (I guess it's just clever enough not to do that?)

I've only got limited experience with Prisma, but I understand you can view it as an extra back-end GraphQL layer interfacing between your own GraphQL server and your data (ie the database).

Your first model ( datamodel.prisma ) uses enhanced Prisma syntax and directives to accurately describe your data, and is used by the Prisma layer, while the second model uses standard GraphQL syntax to implement the same object as a valid, standard GraphQL type, and is used by your own back-end.

In effect, if you looked into it, you'd see the DateTime type used by Prisma is actually a String , but is likely used by Prisma to validate date & time formats, etc., so there is no fundamental discrepancy between both models. But even if there was a discrepancy, that would be up to you as you could use resolvers to override the data you get from Prisma before returning it from your own back-end.

In short, what I'm trying to say here is that you're dealing with 2 different GraphQL layers: Prisma and your own. And while Prisma's role is to accurately represent your data as it exists in the database and to provide you with a wide collection of CRUD methods to work with that data, your own layer can (and should) be tailored to your specific needs.

As for your resolver question, parent in this context will hold the object returned by the parent resolver. Imagine you have a getTodo query at the root Query level returning a single item of type ToDo . Let's assume you resolve this to Prisma's default action to retrieve a single ToDo. According to your datamodel.prisma file, this query will resolve into an object that has an added property (which will exist in your DB as the createdAt field, as specified by the @createdAt Prisma directive). So parent.added will hold that value.

What your added resolver does is transform that original piece of data by turning it into an actual Date object and then formatting it into a UTC string, which conforms to your schema.js file where the added field is of type String! .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM