Show Calendar — Part 1: Setting Up the API

Marcus Stenbeck
4 min readJan 14, 2018

--

The Show Calendar project explores developing an app with the Event Sourcing and CQRS patterns. The goal is to understand how good these patterns are for fast-changing projects, like startups.

The project is implemented in JavaScript with a GraphQL API, but the ideas should work in any language.

Photo by Randall Bruder on Unsplash

We’re going to set up a GraphQL API that’ll serve as our entry point into the show calendar system.

The first step I usually take when starting my implementation is to think of the data model.

The Show data model

I want to keep it simple — we don’t need anything fancier than a single type Show. Yes, we could have a more advanced data model, but in the name of simplicity, this is a reasonable starting point.

Show {  
title: String
time: DateTime
host: String
location: String
}

I know this model has problems. For example, a show may, in reality, have more than one host. But instead of planning for that I’m going to later introduce it as a change of requirements. One of the points of this project is to see how easy or hard it is to handle this type of change.

(It’ll be interesting to see how things go… especially if there’s a pre-existing “legacy database” with a bunch of data that was added before we “knew” about the “new” requirement. Alas, onwards!)

CQRS… ?

We’re going to apply the Command Query Responsibility Separation pattern, or CQRS. This means splitting the functionality of reading and writing (e.g. creating, reading, updating) into separate things — Queries and Commands.

Queries are for reading data.

Commands are for writing data.

Our system will be simple and have only one query.

## Show Calendar Queries ##
GetShow -> Shows

The most basic command in the system is adding a show. For the time being we have no business rules. In other words, we can add multiple shows with exactly the same information.

## Show Calendar Commands ##
AddShow(title, time, host, location) -> void

And that’s it for now. Later on we might add more commands or queries, but for simplicity’s sake this is enough.

It’s coding time!

Implementing stuff always makes me understand things better. The Show Calendar app will be implemented in Node.js with a GraphQL API.

If you haven’t already, get the starter kit here: Part 0 — Starter Kit.

Set up the GraphQL API

In src/schema/index.js, set up one query allShows and one mutation addShow. At the same time, add the Show GraphQL type.

The CQRS pattern’s Query and Command concepts map really nicely onto GraphQL’s Query and Mutation types.

CQRS Query — GraphQL Query

CQRS Command — GraphQL Mutation

Now, start the server with npm start and go to the GraphiQL playground (localhost:3000/graphiql - don't forget the the i!) and paste the below query and mutation.

Note: npm start from the starter kit will automatically restart the server when it detect that you've saved a code change. No need to start and stop!

query GetShows {
allShows {
title
time
host
location
}
}
mutation AddShow {
addShow(
title: "Trolling"
time: "2018-04-01T13:37:00Z"
host: "Trollface"
location: "Reddit"
)
}

Using the play button, run the GetShows query and you should receive the following response.

{
"data": {
"allShows": []
}
}

Running the AddShow mutation should result in the following.

{
"data": {
"addShow": true
}
}

However, if you run the GetShows query again we still receive an empty array—there's nothing hooked up to the API yet.

Before fixing that let’s fix another tiny issue.

The time value can currently be any string, but only valid time strings should be allowed.

Making sure time is time

In the Shows type, we've accepted String as the GraphQL type for the timefield. While this could work for some applications I'd rather have it be a type that actually represents date and time.

Let’s import GraphQlDateTime from the graphql-iso-date package and add it as the DateTime scalar to the GraphQL API.

I’m not going to explain exactly what a scalar is, just know that if the DateTimereceives anything else than a valid ISO time string it'll throw an error.

Now you’ll receive a GraphQL error if you attempt to pass an invalid time string, like "2017-13-01T12:00:00Z" (the 13th month?).

Let’s return some data

We’re done with the GraphQL API for now, but it’d be fun if the allShows()query returns some shows.

For the time being, let’s return some mock data.

Running GetShows is now a little bit more interesting.

Summing it up

Although playing with mock data is cool and all, it’s way more interesting if the AddShow command saves the show so the GetShows query can read it. Time for some plumbing...

If you want to you could now hook this GraphQL API up to a frontend app (for example using apollo-client).

In Part 2 we’ll make the API work by using a re-e-eally simple in-memory storage: an array. We’ll also talk a lot about events and how what we store is, like totally, a simple variant of Event Sourcing.

--

--

Marcus Stenbeck

Very interested in not fitting in. I invite you to criticize and pick apart everything and anything I’ve written. http://twitter.com/marcusstenbeck