Generate your Apollo DataSources
Using GraphQL as your aggregation layer for your microservices is great, but writing all the code for connecting to them is not. Not only that part is boring, error-prone, it also gives you untyped code which could (and will!) result in runtime errors.
Our vision at xolv.io is to
"eliminate the problematic and mundane so the interesting can flourish."
Let me show you how you can use the Chimp DataSources generator to achieve just that.
Continue reading or watch the video version here:
Setup
If you want to follow along, please clone this repository and start the monorepo app: https://github.com/xolvio/chimp-gql-federation-example. Our example is straightforward so you should be able to get the idea by watching the video or just reading through the article. If you are in hurry you can also skip directly to the "Generate" section
We have a standard java spring microservice. We will use two of its endpoints. One adds a list, another returns all lists.
Let's first hit them manually, at the beginning, we can see that the list is empty to start with:
We can add a list:
And verify that it was added:
Now let's create our GraphQL app.
Then enter that directory and install dependencies.
Now let's install our generator and the apollo-datasource-rest package
Generate
With the tooling in place we can finally generate the data sources:
We need to add our newly generated DataSource to our app, in our scaffold, the function that is responsible for that is in src/dataSources.ts
Now let's create a schema with our Query for getting all the lists:
src/Lists.graphql
Now we run the generator to create all the code necessary for implementing that new Query:
You should see a new directory called "queries" with two files GetAllListsQuery.ts which is the resolver for our Query, and GetAllListsQuery.spec.ts which is a specification for it.
In the spirit of TDD let's start with the test. In-line comments explain
src/queries/GetAllListsQuery.spec.ts
That test will fail with "Error: not implemented yet" which comes from our resolver, let's implement it then.
Easy. Being guided by the test we know that we should call the controller getLists method without any arguments, and pass the data through.
Now for the slightly more complicated, mutation.
Let's add it to our schema
src/Lists.graphql
And generate the necessary code:
Again, we will start with the test for the mutation:
src/mutations/AddListMutation.spec.ts
And now for the implementation. This time we are using args to pass the name to the controllers createList method.
src/mutations/AddListMutation.ts
Note - everything is typed. You can try to use args.text instead of args.name, mistake the createList method, or just call it without returning. The same goes for the test - you can try to create the variables object that doesn't match the GraphQL Schema, or resolve an object with a different shape than the one defined by the createList method - you could make tests like that pass ignoring the types, but the mutation would fail run-time.
With everything set up let's make sure that our code actually works!
Let's open the graphql playground and run our query. The combination of tests, types and generated scaffolding gives us very high confidence that things will work as expected.
And mutation:
You can see the resulting code here: https://github.com/xolvio/generated-datasources-simple-example.git
This is clearly a very simple example, but more complex cases should be as straightforward. The actual complexity will come from your business logic, not from setting things up and gluing them together.
We've effectively removed the mundane. It's your turn to make the interesting (complex, valuable from a business standpoint) flourish!
Let me know if you have any questions or thoughts in the comments below.