DEV Community

Cover image for GraphQL pre-primer for app developers
Eric Donovan
Eric Donovan

Posted on

GraphQL pre-primer for app developers

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"
}
Enter fullscreen mode Exit fullscreen mode

the server replies with this response:

HTTP/1.1 201 OK
Content-Length: 47
Content-Type: application/json

{
  "message": "thanks for submitting a tree"
}
Enter fullscreen mode Exit fullscreen mode

The body can contain HTML, JSON or any other text based content. 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/addtree?name=trevor HTTP/1.1
Accept: application/json
Host: trees.com
Enter fullscreen mode Exit fullscreen mode

(The response is the same as with a POST)

HTTP is almost ubiquitous, it's how most of the web works, including your favourite website. There are 3 common ways that apps build on top of HTTP to 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
Enter fullscreen mode Exit fullscreen mode

the response (just showing the body):

[
  {
    "id":"101",
    "name":"tiffany",
  },
  {
    "id":"102"
    "name":"trevor",
  },
  {
    "id":"103",
    "name":"tricia",
  }
]
Enter fullscreen mode Exit fullscreen mode

and then for each tree id, request:

GET /someapi/trees/101 HTTP/1.1
Enter fullscreen mode Exit fullscreen mode

the response:

{
  "id": 101,
  "name": "tiffany",
  "fullName": "tiffany the tree",
  "description": "brown with green bits"
  "imgUrl": "http://www.treeimages.com/oaktree.jpg"
{
Enter fullscreen mode Exit fullscreen mode

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
        }
      }
    }"
}
Enter fullscreen mode Exit fullscreen mode

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"
        }
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
}
Enter fullscreen mode Exit fullscreen mode

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

Discussion (0)