How to make GraphQL automatically insert current UTC upon mutation?

Viewed 4144

My mutation code looks like this:

Mutation: {
  addPost: async (parent, args) => {
    // Add new post to dbPosts
    const task = fawn.Task();
    task.save(
      dbPost,
      {
        _id: new mongoose.Types.ObjectId(),
        title: args.title,
        content: args.content,
        created: args.created,
        author: {
          id: args.author_id,
          first_name: args.author_first_name,
          last_name: args.author_last_name,
        }
      }
    );
  }
}

The schema I'm working with is defined as:

scalar DateTime

type Query {
  posts: [Post],
  post(id: ID!): Post,
}

type Mutation {
  addPost(
    title: String!,
    content: String!,
    created: DateTime!,
    author_id: String!,
    author_first_name: String!
     author_last_name: String!): Post,
}

type Post {
  id: ID!
  title: String!,
  content: String!,
  author: Author!,
  created: DateTime,
}

As apparent, I'm also using a custom scalar to handle date/time values. This custom scalar, DateTime resolves as:

const { GraphQLScalarType } = require('graphql/type');

const tmUTC = () => {
  const tmLoc = new Date();
  return tmLoc.getTime() + tmLoc.getTimezoneOffset() * 60000;
};

DateTime = new GraphQLScalarType({
  name: 'DateTime',
  description: 'Date/Time custom scalar type',
  parseValue: () => { // runs on mutation
    return tmUTC();
  },
  serialize: (value) => { // runs on query
    return new Date(value.getTime());
  },
  parseLiteral: () => {
    return tmUTC();
  },
});

module.exports = DateTime;

Now this works fine and I'm able to insert and retrieve entries with the timestamp as expected. However, I still have to pass a dummy argument for the created field in order for the DateTime resolver to kick in:

mutation{
  addPost(
    title: "Ghostbusters",
    content: "Lots and lots of ghosts here...",
    created: "",
    author_id: "5ba0c2491c9d440000ac8fc3",
    author_first_name: "Bill",
    author_last_name: "Murray"
  ){
    title
    content
    id
    created
  }
}

I can even leave that field blank and the time will still get recorded. But I cannot just leave it out in my mutation call. Is there any way to achieve this? The objective here is to have GraphQL automatically execute the DateTime resolver without the user having to explicitly enter a created field in the mutation call.

1 Answers

in your mutation, remove the requirement for the created to be required

type Mutation {
  addPost(
    title: String!,
    content: String!,
    // created: DateTime!, changed in next line
    created: DateTime, // no ! means not required
    author_id: String!,
    author_first_name: String!
     author_last_name: String!): Post,
}

Then in your task merge in the created arg if it is not

  addPost: async (parent, args) => {
    // if args does not have created, make it here if it is required by task
    const task = fawn.Task();
    task.save(
      dbPost,
Related