Reputation: 4357
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.
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.
Upvotes: 3
Views: 3782
Reputation: 4357
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.
Upvotes: 5