Apollo Server is a GraphQL server that you can set up in minutes and use with your existing data source (or REST API). You can then connect any GraphQL client to it to receive the data and take advantage of GraphQL benefits, such as type-checking and efficient fetching.
We’re going to get a simple Apollo server up and running that will allow us to query some local data. We’re only going to need three files for this:
- schema.ts to set up our data model
- resolvers.ts to set up how we’re going to populate the data fields in our schema
- Our main.ts where the server is going to launch
We’ll start by creating them:
touch schema.ts resolvers.ts main.ts
Let’s go through setting up each.
Our schema.ts
file describes our data. In this case, our data is a list of dinosaurs. We want our users to be able to get the name and a short description of each dino. In GraphQL language, this means that ‘Dinosaur’ is our type, and ‘name’ and ‘description’ are our fields. We can also define the data type for each field. In this case, both are strings.
This is also where we describe the queries we allow for our data, using the special Query type in GraphQL. We have two queries:
- ‘dinosaurs’ which gets a list of all dinosaurs
- ‘dinosaur’, which takes in the name of a dinosaur as an argument and returns information about that one type of dinosaur.
We’re going to export all this within our ‘typeDefs,’ type definitions, variable:
export const typeDefs = `
type Dinosaur {
name: String
description: String
}
type Query {
dinosaurs: [Dinosaur]
dinosaur(name: String): Dinosaur
}
`;
If we wanted to write data, this is also where we would describe the Mutation to do so. Mutations are how you write data with GraphQL. Because we are using a static dataset here, we won’t be writing anything. But we’ve already written about how you can set up GrahQL and Deno to work with an external data source and read/write to that database in our [GraphQL guide](link to article when its up).
A resolver is responsible for populating the data for each query. Here we have our list of dinosaurs and all the resolver is going to do is either a) pass that entire list to the client if the user requests the ‘dinosaurs’ query, or pass just one if the user requests the ‘dinosaur’ query.
const dinosaurs = [
{
name: "Aardonyx",
description: "An early stage in the evolution of sauropods.",
},
{
name: "Abelisaurus",
description: '"Abel\'s lizard" has been reconstructed from a single skull.',
},
];
export const resolvers = {
Query: {
dinosaurs: () => dinosaurs,
dinosaur: (_: any, args: any) => {
return dinosaurs.find((dinosaur) => dinosaur.name === args.name);
},
},
};
With the later, we pass the arguments from the client into a function to match the name to a name in our dataset.
In our main.ts
we’re going to import the apollo server as well as graphql and our typeDefs from the schema and our resolvers:
import { ApolloServer } from "npm:@apollo/server";
import { startStandaloneServer } from "npm:@apollo/server/standalone";
import { graphql } from "npm:graphql";
import { typeDefs } from "./schema.ts";
import { resolvers } from "./resolvers.ts";
const server = new ApolloServer({
typeDefs,
resolvers,
});
const { url } = await startStandaloneServer(server, {
listen: { port: 8000 },
});
console.log(`Server running on: ${url}`);
We pass our typeDefs and resolvers to ApolloServer
to spool up a new server, then startStandaloneServer
is a helper function to get the server up and running quickly.
All that is left to do now is run the server:
deno run --allow-net --allow-read --allow-env main.ts
You should see Server running on: 127.0.0.1:8000 in your terminal. If you go to that address you will see the Apollo sandbox where we can enter our ‘dinosaurs’ query:
query {
dinosaurs {
name
description
}
}
This will return our dataset:
{
"data": {
"dinosaurs": [
{
"name": "Aardonyx",
"description": "An early stage in the evolution of sauropods."
},
{
"name": "Abelisaurus",
"description": "\"Abel's lizard\" has been reconstructed from a single skull."
}
]
}
}
Or if we want just one ‘dinosaur’:
query {
dinosaur(name:"Aardonyx") {
name
description
}
}
Which returns:
{
"data": {
"dinosaur": {
"name": "Aardonyx",
"description": "An early stage in the evolution of sauropods."
}
}
}
You can learn more about Apollo and GraphQL on the Apollo site. You can learn more about using Deno and GraphQL with a real database in our [GraphQL guide](link to article when its up).