In this tutorial, you will create a Habits Tracker API service, which will consist of the
Habit model. By accessing the
/graphql URL, you will read (query) and write (mutations) new data for our habits.
Webiny framework provides different scaffolding tools. What you will use is the GraphQL Apollo service scaffold to create the API service.
Before adding more functionalities, you will learn the
mutations in the
How to GraphQL section. Then, you will test the GraphQL service with the out-of-the-box TDD setup from Webiny.
You can find the example repo for this tutorial here.
We have an active community on slack. If you struggle in any part of the tutorial, talk to the core-team, and get help. Webiny team is always there for any questions.
First, let’s go through the core concepts used in this tutorial.
Serverless architectures are application designs that incorporate third-party “Backend as a Service” (BaaS) services, and/or that include custom code run in managed, ephemeral containers on a “Functions as a Service” (FaaS) platform. Resource here
At its core, GraphQL enables declarative data fetching where a client can specify what data it needs from an API. Instead of many endpoints that return fixed data structures, a GraphQL server only exposes a single endpoint and responds with the data a client asked for. - Resources here.
Webiny is the easiest way to adopt serverless.
It is created with technology and tools you know and Love:
- React → For everything related to UI.
- Apollo GraphQL → for everything GraphQL (both React and API).
- MongoDB database → as our go-to database.
- TypeScript → to make coding with plugins as an enjoyable experience.
If you have ever used these technologies, you already know Webiny = )
How to GraphQL
As noted in the GraphQL website. GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data.
Let’s go through the fundamental language constructs of GraphQL.
Defining types as well as sending queries and mutations.
We define the schema of our API with the GraphQL type system Schema Definition Language (SDL) → Which is the syntax for writing schemas.
Fetching Data With Queries
As we noted earlier, the Main GraphQL API URL is the URL we care about the most. The Main GraphQL API is the single endpoint.
GraphQL is about asking for specific fields on objects. It's completely flexible and lets the client decide what data is needed.
The client needs to send more information to the server to express its data needs. This information is called a Query.
In a GraphQL query, each field can have 0 or more arguments if specified in the GraphQL schema.
One of the significant strengths of GraphQL is it allows for querying nested information. For example, to load all the habits that each person has written as more info:
Next to requesting information from a server with queries, we can change server-side data through mutations.
With GraphQL, we do these changes with so-called mutations.
Writing Data with Mutations
There are three kinds of mutations:
- creating new data
- updating existing data
- deleting existing data
Mutations generally follow the same syntactical structure as queries. What differentiates them from queries is that they always need to start with the mutation keyword.
Notice that similar to the query that you wrote before, the mutation also has a root field, the createHabit root field. You also learned about the concept of arguments for fields.
createHabit fields take two arguments that specify the habits title and habit score. Like with the query, you are also able to determine the payload for the mutation, in which you can ask for different properties of a new person object.
Being able to query information when sending mutations can be a powerful tool that allows retrieval of data from the server in just a single round trip.
The server response from the above mutation will look as below.
Precisely as with queries, the server response is shaped according to the mutation that was sent.
To create the Serverless GraphQL API, you will need to set up a Webiny project.
The base prerequisites to create a Webiny project are:
- node.js >= 10.14.0
- yarn < 2.0
- or you can just run
npm install yarn -g
- AWS account with an IAM user for programmatic usage
- you can follow this guide
- MongoDB database in the cloud
Make sure to set up all the above requirements to continue with the next steps.
When you create your Webiny project and deploy it with
yarn webiny deploy api --env=local, the output of this command will look like below.
For now, the Main GraphQL API URL is what we care about the most.
Using this URL, you can access the
GraphQL playground in which you can see the complete GraphQL schema created from all of the services that Webiny provides.
Check out the schema below.
When you create your API service, you will see your APIs
Mutations sections. That means you have successfully created and deployed our API service.
Learn more about Webiny API Architecture here.
Serverless API with Webiny
Webiny Project Structure
Before continuing to build the API service, let’s see how Webiny projects are organized.
Check out the Webiny serverless-api project structure in the image below:
To learn more about the Webiny project structure, check out our docs here.
The one folder that is important for us is the
As you can see, these are other folders of individual apps that Webiny provides out of the box. These folders represent the API code that is triggered in the Cloud.
Our goal is to create our API service in the
In terms of deployments, the resources.js file is essential. In this file, we have all of the Cloud resources that are necessary for the Webiny API to work.
Creating API Service
Webiny scaffold is a tool that you can use to set up different ready-made services. It offers you a couple of scaffolds.
The one we need for our project is the GraphQL Apollo Scaffold.
We will create a minimal API service, which we will name it the habits-tracker API. It will consist of one model, the habit model. You will be able to access the
/graphql URL, by querying and writing new habits.
You need to provide the location of our new API service in the
api folder because the
API folder represents the whole Webiny API stack, and that's the location where you want to have our API service.
Every Apollo service that you create consists of different models. The core data model that you will have will be the Habit model.
As you can see in the image below, the
habits-tracker folder is inside the
API folder. Except for the
habits-tracker folder, there are some other changes.
We mentioned earlier, the resources.js file represents the whole cloud infrastructure that needs to be deployed. The scaffolding tool created another entry in the resources.js file that describes the newly added API. Check the image below.
Habits tracker API
We mentioned earlier that Webiny has a simple system of plugins that powers both the React apps and the API services. As soon as you begin developing something with Webiny, you'll be working with plugins.
The source code of the API service is in the
src folder. The
plugins folder is the place that contains all the plugins we are using.
The two most essential plugins are the graphql and the model plugin. We will go through each of the plugins and see what they represent.
The models.ts file has a list of commodo models that we want our GraphQL to have.
Commodo is a set of higher order functions (HOFs) that let you define and compose rich data model objects.
The Commodo library is part of the Webiny project by default. It enables you to create data models.
The graphql.ts file represents the schema we want the API to have. The scaffolding tool creates the whole schema for us. We will have basic getHabit and listHabits queries and the basic mutations in place such as createHabit, deleteHabit, and updateHabit.
This is a very convenient and easy to start with for every developer to develop their custom API services.
To see the updated GraphQL schema, you need to deploy the created project by running this command.
If you are deploying a completely new service, you deploy the whole API stack. After the first deploy of the created service, you can continue deploying only that particular API service.
Now you can open the Main GraphQL URL, and see the updated GraphQL schema with Habits queries.
And the Habits mutations.
Extend the API service
We mentioned in the Habits Tracker API section that the scaffolding tool setup provides two plugins. They are the graphql and the model plugins.
In the models.ts file, we will add another field in the Habit model such as
habitScore. As shown in the image below
After you change the model, you will need to change the GraphQL schema in the GraphQL too in the
You have the
Habit type; besides the
Habit, you will have the
input type used for mutations in writing and updating data. So whenever you have the Habit Type mentioned, you need to add the
habitScore field. You have the
Sort types that are used when you query for Habits.
See the changes in the image below.
Now you will deploy only the new API service you created, for the changes to take place in the cloud.
The API service name is in the
resources.js file; you can look for the Habits-tracker entry. Check the image below.
Deploy the new API service by running this command:
As you can see, since you deployed the API Service, the deploy time is 13 seconds.
You can now open the Main GraphQL API and see the newly added fields in the Habit model.
Now, you can test out the API service by creating a new Habit. Check out the image below.
As you can see, you got an error
Not authorized. - To create new data, you need to create a Personal Access Token from the Admin UI. Check your profile by clicking on your image profile and then in your name.
Click on the Personal Access Tokens field, as shown in the image below:
And provide a token name in the input, as shown in the image below.
Copy the provided Personal Access token
Now we are ready to read queries and write mutations to the Habit model = )
Debug with TDD
One of the challenges of Cloud Development is debugging and slow iterations.
For every change you do, you have to deploy them to the Cloud to ensure everything works as expected.
The Debugging process is prolonged; you can use console logs in the code and then re-deploy the code to see the cloud watch logs.
To experience an excellent flow of work, you write tests. As you may be noticed, in the
Habits Tracker folder, you had a folder called
The scaffolding tool created the
__tests__ folder for us. With the existing tests, you are creating the local GraphQL Service, by creating the same function that the API Gateway will execute in the Cloud.
This enables us to invoke the function locally, and assert certain things are in order.
This process is much faster because by running the
yarn test command, the tests that the scaffold created will be executed.
You have one test for the CRUD operations for the base model, and one for the validation if the title field is not valid. See the image below.
The tests are passing because I already added the
habitScore field on the tests.
You can expand your API with other functionalities, and by adding the tests, you can be assured that the API is working, by quickly debugging if something goes wrong.
If you have any question, as we noted earlier, join our Slack Community here. Our team is always there for any questions.
- Webiny Quick start
- GraphQL Queries and Mutations
- GraphQL Crash Course in 10 pics
- Webiny API Architecture
- API Development with Webiny.
With a couple of steps, you were able to start testing your custom API service immediately.
You learned the
GraphQL fundamentals such as
mutations and tested your knowledge with the Webiny API service scaffold.
You can continue developing your API service with additional models and functionalities.
Want to learn more about
Serverless APIs with Webiny? Check our docs here.
Until next time, happy Coding = )