Ballerina GraphQL with multiple datasources
Source code
The full source code for the scenario can be found in ballerina-scenarios repo.
Sample use case
The data source to the GraphQL server can be anything such as a database, API, or service that holds data. Also, GraphQL can interact with any combination of data sources. In this use case, let’s see how we can implement a GraphQL server using the Ballerina language to expose data in the MySQL database and data retrieved via another API call.
The MySQL database holds data about a book store, and it has book data and author data. Additional information related to Books is retrieved using Google Books API. Clients of the book store can do the following operations via the GraphQL server.
- Retrieve the details of all the books
- Retrieve the details of the book by providing the book name
- Add new books to the database
The information sources for the above operations are as follows.
- Title, published year, ISBN number, author name, author country - Retrieved from DB
- Average rating and rating count - Retrieved from Google Books API filtered using ISBN number of the book.
E.g.: https://www.googleapis.com/books/v1/volumes?q=isbn:9781101042472
Set up the Database
Create the sample MySQL database and populate data with the data.sql script as follows.
mysql -uroot -p < /path/to/data.sql
Run the code
Execute bal run
command within the bookstore
project folder.
Test the service
To call the GraphQL server, we need to use a client. We can do this from the command line with curl by sending an HTTP POST request to the endpoint, passing the GraphQL query as the query field in a JSON payload. If you prefer to use a graphical user interface, you can use clients such as GraphiQL or Altair.
For all the requests the endpoint is : http://localhost:4000/bookstore
Sample Request 1: Get the titles of all books
GraphQL query:
{allBooks {title}}
Response:
{
"data": {
"allBooks": [
{ "title": "Pride and Prejudice" },
{ "title": "Sense and Sensibility" },
{ "title": "Emma" },
{ "title": "War and Peace" },
{ "title": "Anna Karenina" }
]
}
}
CURL command to request the same: curl -X POST -H "Content-type: application/json" -d '{ "query": "{allBooks {title}}" }' 'http://localhost:4000/bookstore'
Sample Request 2: Get more details of all books
This is where the true power of GraphQL comes in. Users can request the exact information they need in the format they prefer without having different endpoints, but just by changing the query.
GraphQL query :
{allBooks {title, author{name}, reviews{ratingsCount, averageRating}}}
Response :
{
"data": {
"allBooks": [
{
"title": "Pride and Prejudice",
"author": {
"name": "Jane Austen"
},
"reviews": {
"ratingsCount": 1,
"averageRating": 5
}
},
{
"title": "Sense and Sensibility",
"author": {
"name": "Jane Austen"
},
"reviews": {
"ratingsCount": 3,
"averageRating": 4
}
},
{
"title": "Emma",
"author": {
"name": "Jane Austen"
},
"reviews": {
"ratingsCount": null,
"averageRating": null
}
},
{
"title": "War and Peace",
"author": {
"name": "Leo Tolstoy"
},
"reviews": {
"ratingsCount": 5,
"averageRating": 4
}
},
{
"title": "Anna Karenina",
"author": {
"name": "Leo Tolstoy"
},
"reviews": {
"ratingsCount": 1,
"averageRating": 4
}
}
]
}
}
CURL command to send the same request:
curl -X POST -H "Content-type: application/json" -d '{ "query": "{allBooks {title, author{name}, reviews{ratingsCount, averageRating}}}" }' 'http://localhost:4000/bookstore'
Sample Request 3: Get details of books with input parameter
GraphQL Query:
{bookByName(title: "Emma") {title, published_year}}
Response:
{ "data": { "bookByName": [{ "title": "Emma", "published_year": 1815 }] } }
CURL Command to send the same request:
curl -X POST -H "Content-type: application/json" -d '{ "query": "{bookByName(title: \"Emma\") {title, published_year}}" }' 'http://localhost:4000/bookstore'
Sample Request 4: Mutation to insert data into the database
GraphQL Query:
mutation {addBook(authorName: "J. K. Rowling", authorCountry: "United Kingdom", title: "Harry Potter", published_year: 2007, isbn: "9781683836223")}
Response:
{
"data": {
"addBook": 6
}
}
CURL Command to send the same request:
curl -X POST -H "Content-type: application/json" -d '{ "query": "mutation {addBook(authorName: \"J. K. Rowling\", authorCountry: \"United Kingdom\", title: \"Harry Potter\", published_year: 2007, isbn: \"9781683836223\")}" }' 'http://localhost:4000/bookstore'