1. Getting Started
Learn how to start a new GraphQL API project from scratch using Node.js and JavaScript.
Last updated
Learn how to start a new GraphQL API project from scratch using Node.js and JavaScript.
Last updated
During this step, you want to ensure that at least the following things are taken care of:
You can use the latest (modern) JavaScript syntax (most likely using Babel )
You can launch the app by running yarn start
which is a commonly used convention.
When you make changes to the source code, the app (API) automatically restarts (see Nodemon).
Node.js debugger is configured and ready to be used when needed.
Assuming that you already have Node.js and Yarn (or, NPM) installed, bootstrap a new Node.js project by running:
Create .babelrc
file containing Babel configuration. Add "start"
script to the package.json
file:
Note that the actual versions of all the listed dependencies above may differ from what you would end up having in your package.json
file, but it shouldn't be a problem.
Finally, create src/index.js
file that will serve as an entry point to the (Express.js) app:
At this point, when you launch the app by running yarn start
and navigate to http://localhost:8080/
in the browser's window, you must be able to see the following:
Congratulations! This means that the step #1 is complete and we can move on to the next one — creating our first GraphQL schema required by the express-graphql
middleware.
Basically, you create an GraphQL API by describing the hierarchy (schema) of all the (query) fields and mutations that the API must support.
Imagine that we need to fetch some OS-related info from the server using this query:
It's asking for arch
, platform
, and uptime
values grouped under the top-level environment
field.
For this particular API we would need to implement just one GraphQL type (Environment
), and one top-level query field environment
. But since, we're planning to add more types and query fields later on, it would be a good idea to group them under src/types
and src/queires
folders. Plus, you would add src/schema.js
file exporting the "schema" GraphQL object type.
In a real-world project, you may end-up having 50+ GraphQL types, depending how big is the project. Taking that into consideration, you may want to export related GraphQL types from the same file. For example, ProductType
and ProductCategoryType
declarations can be exported from the **src/types/product.js
**file.
The Environment
GraphQL type is going to list arch
, platform
, and uptime
fields, alongside their types and resolve()
methods:
Whenever a certain field is requested by the client, the GraphQL API runtime would call the corresponding resolve()
function that would return the actual value for that field. Note that these resolve methods can be async (returning a Promise
).
For the top-level fields, like environment
field in our example, we're going to introduce yet another convention — placing them in multiple files under the src/queries
folder. In many cases, those top-level fields would contain large resolve()
functions and most likely you won't like having all of them within the same file. So, the environment
field is going to be exported from src/queires/environment.js
:
Note, that the field resolves to an empty object {}
. If it would resolve to null
or undefined
the query traversal would stop right there, and the GraphQL query (from the example above) would resolve to:
You would also need src/queries/index.js
and src/types/index.js
re-exporting everything from the sibling files:
The environment
field declaration we just created is going to be used in the root GraphQL object type:
Finally, we're going to pass this schema type to the express-graphql
middleware inside src/index.js
:
With all that in place, you must be able to test our first GraphQL query using GraphiQL IDE that express-graphql
middleware provides out of the box:
Inside of the resolve()
methods we would often need access to the (request) context data such the currently logged-in user, data loaders (more on that later), etc.
For this purpose, let's create Context
class and pass it to the express-graphql
middleware alongside the schema:
Just for quick demonstration, let's see how to use this context object inside of a resolve()
method:
Sooner or later you may bump into a situation where you would need to debug your code. It would be wise to ensure that debugging is working OK, even before you actually need it. In case with VS Code, setting up the debugger takes just two simple steps:
Pass --insepect
argument to nodemon
.
Create a launch configuration that would attach to an existing Node.js process.
For the first step, you can copy and paste the start
script inside of package.json
file as follows:
And then create .vscode/launch.json
file instructing VS Code how it should launch the debugger:
The source code for this chapter is available on GitHub and CodeSandbox (live demo).