visit
We'll be building our app using, so you should have at least version 12 installed on your machine. Create a directory called slashql_bookstore and navigate into it from the command line.
Setting up Slash GraphQL
is easy—you can instantly sign-in with your GitHub account. The platform offers a free trial which will work for this article (then moves to a $9.99/mo flat fee for up to 5GB data).Defining the GraphQL schema
Every GraphQL server has a strongly typed schema, which defines the objects and fields available to consumers.Click on "Schema", and paste the following lines:type Book {
id: Int!
isbn: Int!
title: String! @search(by: [fulltext])
author: Author!
}
type Author {
id: Int!
firstname: String!
lastname: String!
}
Setting up the data
Let's move on to inserting data. We can use the API Explorer to not only add data, but query for it, too. In order to populate our GraphQL backend, we'll define a list of books and their authors through a mutation that Slash GraphQL conveniently provides for us, based on our schema:mutation AddData {
addBook(input: [
{id: 1, title: "The Sound and The Fury", isbn: 9780394747743, author: {id:1, firstname: "William", lastname: "Faulkner"}},
{id: 2, title: "Light in August", isbn: 9780394711898, author: {id:1, firstname: "William", lastname: "Faulkner"}},
{id: 3, title: "Giovanni's Room", isbn: 9780141032948, author: {id:2, firstname: "James", lastname: "Baldwin"}},
{id: 4, title: "The Fire Next Time", isbn: 9780140182750, author: {id:2, firstname: "James", lastname: "Baldwin"}},
{id: 5, title: "To The Lighthouse", isbn: 9780140274165, author: {id:3, firstname: "Virginia", lastname: "Woolf"}},
{id: 6, title: "Orlando", isbn: 9780241284643, author: {id:3, firstname: "Virginia", lastname: "Woolf"}}
]) {
numUids
}
}
query GetBooks {
queryBook {
title
isbn
author {
firstname
lastname
}
}
}
Building the server
We'll now use to set up a basic API server that will provide users access to this Slash GraphQL source. Our Express server acts as little more than an interface to hand requests off to Slash GraphQL. Its most important lines are these:const BACKEND_URL = "//rampant-arm.us-west-2.aws.cloud.dgraph.io/graphql"
async function fetchGraphQL(operationsDoc, variables) {
const result = await axios({
method: 'POST',
url: BACKEND_URL,
headers: {
'Content-Type': 'application/json',
},
data: JSON.stringify({
query: operationsDoc,
variables,
}),
})
return result.data
}
const query = `
query {
queryBook {
title
isbn
author {
firstname
lastname
}
}
}
`
app.get('/', jsonParser, async (req, res) => {
let gqlResponseData = await fetchGraphQL(query, {})
res.render('index', { books: gqlResponseData.data.queryBook })
})
<div class="container">
{{#each books}}
<div class="row">
<div class="col-md-4">
<h2>{{title}}</h2>
<h4>{{author.firstname}} {{author.lastname}}</h4>
<p><strong>ISBN:</strong> {{isbn}}</p>
</div>
</div>
<hr>
{{/each}}
</div>
Extend the server
As a final step, we want to expose some reviewer data about these books. But we don't want to create dummy data here; instead, we'll use. Make sure you set up an account there and get an API key before continuing.One of the many things that Slash GraphQL excels at is the ability to stitch together disparate sources of data into one GraphQL interface. Perhaps you'll want to make calls to other API endpoints that are under your control. To support this, Slash GraphQL provides the directive, which allows you to implement custom behavior for GraphQL fields and resolvers.First, let's add our rating information to the existing schema:type Rating @remote {
ratings_count: Int!
average_rating: Float!
}
type Book {
# ...
rating: Rating @custom(http: {
url: "//goodreads-api-munger.glitch.me?isbn=$isbn",
method: GET
})
# ...
}
const query = `
query {
queryBook {
title
isbn
rating {
ratings_count
average_rating
}
author {
firstname
lastname
}
}
}
`
<div class="container">
{{#each books}}
<div class="row">
<div class="col-md-4">
<h2>{{title}}</h2>
<h4>{{author.firstname}} {{author.lastname}}</h4>
<p><strong>ISBN:</strong> {{isbn}}</p>
<p>Rating: {{rating.average_rating}} (out of {{rating.ratings_count}} votes)</p>
</div>
</div>
<hr>
{{/each}}
</div>
Also published at