I'm building a GraphQL server from scratch with an API backend, replacing a REST API server. Currently some requests in the existing API server, mainly Create / Update requests that will be mutations in GraphQL, include a request id which is used by the client. This request id is metadata about the request itself not part of the domain resource.
My question is how to model / include request metadata in GraphQL queries and mutations? My only solution so far is to make a request Type, which other types could include as a field so the request data can be included in the mutation return type. However i do not like this approach as it mixes request data into my domain types and this very much feels against the ethos of GraphQL. Is there an accepted way to pass 'arbitrary' e.g. non-domain type data in the response of a query or mutation in GraphQL?
Example - what i would like to avoid:
type UserType {
id: ID
name: String
request: RequestType // mixing request data in with domain type of User
}
type RequestType {
id: ID
}
For others interested in this problem, based on the responses here I have decided that the GraphQL extensions key is good option for adding arbitrary data to a GraphQL response without the data becoming part of your data Graph. In Express-GraphQL, docs on adding an extensions key to responses can be found here: https://github.com/graphql/express-graphql#providing-extensions. A good overview of extensions here: https://marmelab.com/blog/2017/09/06/dive-into-graphql-part-iii-building-a-graphql-server-with-nodejs.html#server-logging
That said, if the request metadata is conceptually part of the domain data then following Kashif's suggestion below of creating ResponseTypes that embed domain Types might be the correct approach.
Since GraphQL was designed to be protocol agnostic, you should use your chosen protocol's metadata pattern. If you're using HTTP, you should pass headers. If you're using WS/STOMP/MQTT/AMQP you can include metadata in each frame.
Alternatively GraphQL has an extensions protocol. You could add a request-id to your responses in the extensions object. Apollo uses extensions for caching, telemetry, etc.
We've been using GraphQL in production for about a year, we made the mistake of adding metadata into GraphQL and it gets hard to manage. Don't lose out on the benefits from the features of the protocol you're using.
This kind of meta elements are usually passed in HEADERS with each request. And then you can handle those in your GraphQL server as you like
For eg.
//Request Headers
...
X-Request-Id: <Your_Request_Id>
...
Headers work both ways so there shouldn't be any problems using them on client too. Pull them out of the response whenever you need.
However if you really want the requestId in your mutation response then that IS a part of your domain. And there is nothing wrong in have a custom response type, Many existing GraphQL apis do have a custom response type like LoginResponse, RegisterResponse which then wraps around your domain objects but also include extra stuff in meta fields
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With