type Employee {
id: String!
name: String
lastObservedStatus: String
}
type Query {
employees: [Employee]
}
This is a fictional schema to illustrate my question. I have two separate data sources that return lists that need to be joined in order to populate the response. The first data source 'employee list api' is an http API I can query to get an authoritative list of employees that I can use to populate the id
and name
columns. For example, I get a response like this:
[
{"id": "001", "name": "Harry"},
{"id": "002", "name": "Jerry"},
{"id": "003", "name": "Larry"}
]
I have a second http API 'employee observation log' I can query to get a list of statuses together with the associated ids. The id allows me to associate the number to an entry in the employee record, and I have a record date. There may be more than one status record, but in GraphQL I want to pick only the most recent one. Example response:
[
{"id":"002", "TimeStamp":"2021-07-01T12:30:00Z", "status": "eating"},
{"id":"002", "TimeStamp":"2021-07-01T13:10:00Z", "status": "staring out the window"},
{"id":"001", "TimeStamp":"2021-07-01T16:00:00Z", "status": "sleeping in lobby"}
]
Now, I want the graphQL response to return something like this:
{
"data": {
"employees": [
{
"id": "001",
"name": "Harry",
"lastObservedStatus": "sleeping in lobby"
},
{
"id": "002",
"name": "Jerry",
"lastObservedStatus": "staring out the window"
},
{
"id": "003",
"name": "Larry",
"lastObservedStatus": null
}
]
}
}
Since 'employee list api' is the authoritative source about which employees exist, all queries to the 'employee' field should always trigger a query to that api, but the 'employee observation log' api should only be triggered if the 'lastObservedStatus' field is selected in the query.
For a schema like this, where should the resolvers be registered? I've read that the best practice is to always attach resolvers at the leaf nodes, but I'm not sure how that can be done in this situation. I'm not even sure what happens if you attach a resolver on subfields of a list.
I feel like the correct way to handle this is to attach a lambda resolver to the employees
field, and in the lambda resolver check the query's selectionSetList to check whether or not the 'lastObservedStatus' field has been selected. If not, then the lambda only queries 'employee list api', but otherwise the lambda also queries 'employee observation log' and does something similar to a SQL join before returning the result. But is that the correct way to handle this?