Graphql date range as input field

109 views Asked by At

I am implementing a GraphQL API for a automobile inventory which stores the info like registration, inDate, outDate, etc.

I need to implement a fetch API to retrieve the info of all cars which came in/ went out

  1. on a certain date
  2. or in a certain date range like a week or month

Assuming the current looks like

scalar Date

input QueryArguments {
  registration: string
  inDate: unkownType
  outDate: unkownType
}

type Query {
  automobiles(input: QueryArguments!): [Automobile]
}

type Automobile{
  registration: string
  inDate: Date
  outDate: Date
}

What would be the standard/accepted way for GraphQL input field to support both a single Date and a Date Range.

I came across a stackoverlow article in which it was suggested to use a custom type

type DateRangeInput {
  start: Date
  end: Date
}

It works fine for Date range, but if a single date needs to be provided we should send it in either start or end field or introduce a different field apart from those, but it doesnt look clean in the single date scenario.

UPDATE: Based on Michel Floyd suggestion, I am going with the approach of custom input type.

input DateInput{
    onDates: [Date],
    inRange: DateRangeInput
}
input DateRangeInput {
  start: Date!
  end: Date!
}

Where it supports selection of multiple individual dates, or a date range. Any restrictions should be implemented in resolver.

This approach doesn't look clean, but this option suits my requirement best with current apollo-graphql capabilities.

1

There are 1 answers

4
Michel Floyd On

All your fields in your input type are currently optional. You can add to that:

scalar Date

input QueryArguments {
  registration: string
  inDate: Date
  outDate: Date
  start: Date
  end: Date  
}

type Query {
  automobiles(input: QueryArguments!): [Automobile]
}

Then you can query with any combination of arguments:

query myQuery($input: QueryArguments!) {
  Query(input: $input) {
    … automobile fields
  }
}

QueryArguments could then be:

{ start: '2024-01-01', end: '2024-01-31'}

or:

{ inDate: '2024-01-09' }

Or any combination. Your resolver code would be responsible for ensuring that if start is provided then end also has to be there (if that's what you want).

OR, you can have two input types, each of which is optional.

input QueryArguments {
  registration: string
  inDate: Date
  outDate: Date
}

input DateRange {
  start: Date
  end: Date
}

and then define your query as:

type Query {
  automobiles(input: QueryArguments, range: DateRange): [Automobile]
}

Note the lack of an exclamation point after either of those types, that means both are optional but your resolver can enforce that at least one has to be there.