We can use GraphQL in various ways, but for this article we're going to focus on the most common situation faced by mobile client app developers: GraphQL over HTTP
HTTP
This means sending:
- a method (like POST, PUT, GET etc)
- headers
- and a body
And receiving back:
- an HTTP Code (like 200 or 404)
- headers
- and a body.
Here's an example HTTP POST request, we send this to the server:
POST /someapi/addtree HTTP/1.1
Accept: application/json
Content-Type: application/json
Content-Length: 73
Host: trees.com
{
"name": "tiffany the tree",
"description": "brown with green bits"
}
the server replies with this response:
HTTP/1.1 201 OK
Content-Length: 47
Content-Type: application/json
{
"message": "thanks for submitting a tree"
}
The body can contain HTML, JSON or any other text based content, or nothing (the response can just be the HTTP code). For a static website it'll be HTML, for an app it's usually JSON, and that's what we've used in the examples above
An HTTP GET however, has no body (the request data is embedded in the URL query string) it looks like this:
GET /someapi/tree?name=trevor HTTP/1.1
Accept: application/json
Host: trees.com
You might get a response like this back:
HTTP/1.1 200 OK
Content-Length: 47
Content-Type: application/json
{
"id":"102",
"name":"trevor",
"description": "green with brown bits"
}
HTTP is almost ubiquitous, it's how most of the web works, including your favourite website. There are 3 common ways that apps built on top of HTTP communicate effectively with a server side, let's quickly cover each of them:
RESTful style
For our RESTful style tree service, things might look like this:
request (just showing the HTTP method line):
GET /someapi/trees HTTP/1.1
the response (just showing the body):
[
{
"id":"101",
"name":"tiffany"
},
{
"id":"102",
"name":"trevor"
},
{
"id":"103",
"name":"tricia"
}
]
and then for each tree id, request:
GET /someapi/trees/101 HTTP/1.1
the response:
{
"id": 101,
"name": "tiffany",
"fullName": "tiffany the tree",
"description": "brown with green bits",
"imgUrl": "http://www.treeimages.com/oaktree.jpg"
{
RESTful style endpoints use the full range of HTTP methods and can be pretty popular with server side devs, and there are some benefits to using HTTP verbs with defined characteristics (for example PUT is defined as being idempotent).
IMO RESTful endpoints can be a little less popular with client app developers (you can see that if you wanted to display a list of tree images, it would require multiple requests to the server side)
GraphQL style
GraphQL requests can be sent inside the body of HTTP POSTs (but GETs are used too), and the GraphQL (Query Language) lets clients specify exactly which fields they want in the response:
request body:
{
"operationName": "TreeList",
"variables": {},
"query": "query
TreeList {
trees {
hasMore
trees {
id
name
imgUrl
}
}
}"
}
response body:
{
"data": {
"trees": {
"hasMore": false,
"trees": [
{
"id": "101",
"name":"tiffany",
"imgUrl": "http://www.treeimages.com/oaktree.jpg"
},
{
"id": "102",
"name":"trevor",
"imgUrl": "http://www.treeimages.com/ashtree.jpg"
},
{
"id": "103",
"name":"tricia",
"imgUrl": "http://www.treeimages.com/birchtree.jpg"
}
]
}
}
}
Getting all the data in one go is better for a client app, and the server only sent us the fields we asked for (id, name, imgUrl). But you'll see the request suddenly got a bit more complicated, and they can get a lot more complicated than that (handling that complication is what a library like Apollo is for)
RPC style
Hang on a second (you might be thinking) why can't the server devs just give me an API like this?
request:
GET /someapi/treesummarieslikeiwantthem HTTP/1.1
response:
{
"id": "101",
"name":"tiffany",
"imgUrl": "http://www.treeimages.com/oaktree.jpg"
},
{
"id": "102",
"name":"trevor",
"imgUrl": "http://www.treeimages.com/ashtree.jpg"
},
{
"id": "103",
"name":"tricia",
"imgUrl": "http://www.treeimages.com/birchtree.jpg"
}
Well... they can! But they might have some good reasons not to. For a large organisation, server sides are often supporting multiple versions of multiple client technologies and giving each of them their own custom endpoint becomes very difficult to maintain.
GraphQL has its complications but it does allow client apps maximum flexibility in asking for exactly what they want, while letting server devs work on a generic solution to support multiple client requirements at the same time.
It's also a great way to create a BFF implementation (Backend For Frontend) which sits between the mobile client apps and various micro-services. That means the mobile apps don't have to re-implement the same micro-services integration work in each client. It can be done once on the server side, and the mobile apps can just talk to the GraphQL service.
Apollo
Because most of the time GraphQL is sent in HTTP POST or GET messages, you could actually talk to a GraphQL server using only an HTTP library like OkHttp.
But don't do that, Apollo helps by autogenerating your network DTOs for you - based on the GraphQL queries that you write using GraphQL (there's a good video on writing GraphQL queries here).
Let's get to the code already!
I hope that's filled in some knowledge gaps, or at least served as a refresher, if you're an android developer here is another post with a full sample app using Apollo3
Top comments (0)