简体   繁体   中英

MongoDB, GraphQL and ISODate type

I have a question about MongoDB ISODate type and GraphQL. I need to declare a mutation in my gql schema that allows to add a document in my Mongo database.

This document has an ISODate property, but in my gql schema, I'am using a String :

mutation addSomething(data: SomeInput)

type SomeInput {
    field1: String
    field2: Int
    created: String
}

My problem is that, in the new document, the created field is in String format (not ISODate), and I was expecting that. But I wonder how to do to make it insert an ISODate instead. Is there a "custom type" somewhere I could use instead a String ?

Thank you

PS: I'am using nodeJS and apollo libraries.

Edit 1 : Trying with the graphql-iso-date package

I have found this package https://www.npmjs.com/package/graphql-iso-date that adds 3 date custom types.

Here is my gql schema :

const { gql } = require('apollo-server');
const { GraphQLDateTime } = require('graphql-iso-date')

const typeDefs = gql`

scalar GraphQLDateTime

type Resto {
    restaurant_id: ID!
    borough: String
    cuisine: String
    name: String
    address: Address
    grades: [Grade]
}

type Address {
    building: String
    street: String
    zipcode: String
    coord: [Float]
}

type Grade {
    date: GraphQLDateTime
    grade: String
    score: Int
}

input GradeInput {
    date: GraphQLDateTime
    grade: String
    score: Int
}

extend type Query {
    GetRestos: [Resto]
    GetRestoById(id: ID!): Resto
}

extend type Mutation {
    UpdateGradeById(grade: GradeInput!, id: ID!): Resto
    RemoveGradeByIdAndDate(date: String, id: ID!): Resto
}

`

module.exports = typeDefs;

This is a test based on the sample restaurants dataset .

So, if I try to call the UpdateGradeById() function like this :

UpdateGradeById(grade:{date:"2020-08-25T08:00:00.000Z",grade:"D",score:15},id:"30075445"){...}

The document is updated but the date is always in String format (as you can see on the screenshot bellow) :

在此处输入图片说明

The date of the last grade in the list is recognized as a string (not as a date).

I can see an improvement though because before I was using the graphql-iso-date date fields were returned in timestamp format. Now they are returned as ISO string. But the insertion does not work as expected.

Ok, I missed to do something important in my previous example : resolvers. So, if like me you want to manipulate MongoDB date type through GraphQL, you can use the graphql-iso-date package like this :

First, modify your schema by adding a new scalar :

const { gql } = require('apollo-server');

const typeDefs = gql`

scalar ISODate

type Resto {
    restaurant_id: ID!
    borough: String
    cuisine: String
    name: String
    address: Address
    grades: [Grade]
}

type Address {
    building: String
    street: String
    zipcode: String
    coord: [Float]
}

type Grade {
    date: ISODate
    grade: String
    score: Int
}

input GradeInput {
    date: ISODate
    grade: String
    score: Int
}

extend type Query {
    GetRestos: [Resto]
    GetRestoById(id: ID!): Resto
}

extend type Mutation {
    UpdateGradeById(grade: GradeInput!, id: ID!): Resto
    RemoveGradeByIdAndDate(date: ISODate!, id: ID!): Resto
}

`

module.exports = typeDefs;

(Here I choose to call my custom date scalar ISODate )

Then, you have to tell how to "resolve" this new ISODate scalar by modifying you resolvers file :

const { GraphQLDateTime } = require('graphql-iso-date')

module.exports = {
    Query: { 
        GetRestos: (_, __, { dataSources }) =>
            dataSources.RestoAPI.getRestos(),

        GetRestoById: (_, {id}, { dataSources }) =>
            dataSources.RestoAPI.getRestoById(id),

    },
    Mutation: {
        UpdateGradeById: (_, {grade,id}, { dataSources }) =>
            dataSources.RestoAPI.updateGradeById(grade,id),

        RemoveGradeByIdAndDate: (_, {date,id}, { dataSources }) =>
            dataSources.RestoAPI.removeGradeByIdAndDate(date,id),
        
    },
    ISODate: GraphQLDateTime

  };

And that's it. Now, date properties in my mongodb documents are well recognized as Date type values.

在此处输入图片说明

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