Getting started
Running
To run locally with an in memory event-store and the default star wars schema
./gradlew run
To run with command line options
.\gradlew run -PappArgs="['-h']"
To run under Docker
docker run -d -p 7002:7002 ianmorgan/graph-store
For a more production like deployment, it is better to use a docker compose file. There is an example on Github. More detail on building and running under Docker is here.
What URL?
By default the service starts on port 7002, so running natively the base url is: http://localhost:7002
The convention under Docker Compose will be: http://graph-store:7002
, but depending
upon how Docker is setup it may also be available on localhost
The running test instance is at: https://graphstore.app
Setting up a Schema
The first step is to register a schema associated with one or more documents. This is in the GraphQL schema format. The examples here are all based on the Star Wars schema from the GraphQL demos.
By default the service will start with a version of the star wars schema with some default data. This can be viewed with
curl -X GET http://localhost:7002/schema
Below is a cut down copy of the schema.
# The episodes in the Star Wars trilogy
enum Episode {
NEWHOPE
EMPIRE
JEDI
}
# A character from the Star Wars universe
interface Character {
id: ID!
name: String!
# The friends of the character, or an empty list if they have none
friends: [Character]
# The movies this character appears in
appearsIn: [Episode]!
}
# A humanoid creature from the Star Wars universe
type Human implements Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
homePlanet: String
}
# An autonomous mechanical character in the Star Wars universe
type Droid implements Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
primaryFunction: String
}
This must be registered by sending to the ‘schema’ endpoint. Note that multiple schemas can be registered, so the name must be clearly identified in the URL
curl -H "Content-Type: application/graphql" -X POST http://localhost:7002/schema/starwars -d @starwars.schema
Note the API doesn’t worry about the semantics of HTTP verbs - its simply GET for basic operations or POST for anything that needs a body
Understanding how GraphQL schemas are used
The graph store allows both a traditional REST API and a GraphQL API to operate over the same schema.
In the schema, each ‘type’ is treated as a distinct document type. An ‘interface’ is a read only document. So in this case we now have a read only ‘Character’ document, and updatable ‘Human’ and ‘Droid’ documents. An example ‘Droid’ document in JSON could be:
{
"id" : "2001",
"name" : "R2-D2",
"appearsIn" : ["NEWHOPE","EMPIRE","JEDI"],
"primaryFunction" : "Astromech"
}
Generally each document can be considered similar to a DDD Aggregate. Its not an exacting mapping, see Comparison to DDD.
Also, its a little bit like a very simple document database, see Comparison to MongoDB
Storing data
Each type in the schema has become a ‘document’, and can be modified. This is done by a traditional REST style operation (future enhancements might support GraphQL mutations).
So to add a new Droid Character.
curl -H "Content-Type: application/json" -X POST http://localhost:7002/docs/Droid -d '{ "id" : "2001", "name": "R2-D2","appearsIn": ["NEWHOPE","EMPIRE","JEDI"] }'
The service performs a basic schema check of the submitted JSON doc and confirms that structure and data types match the GraphQL schema, but it does not validate mandatory fields nor any relationship between fields.
To update, simply pass a fragment. If a field should be removed, set its value to null.
curl -H "Content-Type: application/json" -X POST http://localhost:7002/docs/Droid -d '{ "id" : "2001", "primaryFunction" : "Astromech" }'
This is also available to query as a regular JSON doc (i.e. simple REST, no GraphQL support).
curl -X GET http://localhost:7002/docs/Droid/2001
returns
{
"id" : "2001",
"name" : "R2-D2",
"appearsIn" : ["NEWHOPE","EMPIRE","JEDI"],
"primaryFunction" : "Astromech"
}
Querying with GraphQL
Of course, the whole point of GraphQL is to make issuing queries easier.
curl -X POST -H "Content-Type: application/json" http://localhost:7002/graphql -d '{droid(id: "2001"){name,primaryFunction,appearsIn,friends{name},starships{name,manufacturer}}}'
Any valid GraphQL query can be passed.