{"id":2323,"date":"2020-06-24T11:48:00","date_gmt":"2020-06-24T09:48:00","guid":{"rendered":"https:\/\/frachtwerk.fw-web.space\/?p=2323"},"modified":"2024-09-10T13:56:57","modified_gmt":"2024-09-10T13:56:57","slug":"modern-reactive-web-apis-with-graphql-go-and-server-sent-events-part-1","status":"publish","type":"post","link":"https:\/\/frachtwerk.fw-web.space\/modern-reactive-web-apis-with-graphql-go-and-server-sent-events-part-1\/","title":{"rendered":"Modern, reactive web APIs with GraphQL, Go and Server-Sent Events \u2013 Part 1 (Englisch)"},"content":{"rendered":"\n

Introduction<\/h2>\n\n\n\n

In the course of this two-part article, the interested reader is briefly introduced to the basic of GraphQL and how it compares to traditional approaches. In the second part, an example single-page web application (SPA) is built to demonstrate the use of GraphQL in combination with further modern web technologies. The final project<\/a> provides a clean, opinionated code- and project structure for both backend and frontend and constitutes a good starting point for new apps based on the presented tech stack.<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

What is GraphQL?<\/h2>\n\n\n\n

GraphQL<\/a> is a relatively new (proposed in 2015 by Facebook engineers) approach to designing APIs for (web) backend applications and can be considered an alternative to REST<\/a> or remote-procedure-call (RPC) mechanisms like JSON-RPC<\/a>. In other words, it\u2019s \u201ean open-source data query and manipulation language for APIs\u201c [1]<\/a>. The specification is open-source and actively evolving on GitHub<\/a>. While REST APIs are currently the de-facto standard on the web (although not necessarily all of them being fully mature<\/a>) \u2013 GraphQL starts to gain traction<\/a>.<\/p>\n\n\n\n

Comparison with REST and RPC<\/h2>\n\n\n\n

In contrast to REST, which is primarily structured around resources or entities and RPC-based APIs, which focus on actions or methods, GraphQL is all about the underlying data itself. The consumer of an API \u2013 usually the frontend \/ client-side part of a SPA \u2013 only has to know the schema and structure of the data provided by the API to CRUD<\/a> it. Compared to REST APIs, where the consumer heavily depends on the fixed data structure delivered by the backend API, this is especially beneficial as it introduced a lot more flexibility and decoupling and can save the developer some time making the client-side application tolerant<\/a>. Also, you will probably not need backends for frontends<\/a> anymore.
Essentially, with GraphQL, the consumer asks exactly for what it needs and how it needs it, i.e. your client application tells the backend exactly what to return and in which format. Consuming a GraphQL API is like querying a database, but with more guidance and control.<\/p>\n\n\n\n

Example<\/h2>\n\n\n\n

Let\u2019s look at an example to get a better idea of how GraphQL works, especially in comparison to the REST principles.<\/p>\n\n\n\n

Imagine you have an e-commerce application with products and orders. Every order consists, among others, of a set of products. As the operator of the web shop, you might want to get a list of all orders. With a more or less RESTful API (we neglect the hypermedia controls in the example though), your request-response pair could look like this:<\/p>\n\n\n\n

Request\n-------\nGET \/api\/orders\n\nResponse Body\n-------------\n[\n    {\n        \"id\": 125,\n        \"customerId\": 8977,\n        \"createdAt\": \"2020-06-06T13:40:49.038Z\",\n        \"productIds\": [ 49863176 ]\n    }\n]<\/code><\/pre>\n\n\n\n

So far so good, but potentially you will also want to view the actual products right away. What you got are only ids, for each of which you would have to issue another API call to retrieve it. Alternatively, the API could also return nested objects, like so:<\/p>\n\n\n\n

[\n    {\n        \"id\": 125,\n        \"customerId\": 8977,\n        \"createdAt\": \"2020-06-06T13:40:49.038Z\",\n        \"products\": [\n            {\n                \"id\": 49863176,\n                \"name\": \"Slim T-Shirt navy-blue\",\n                \"price\": 17.90,\n                \"options\": [\n                    {\n                        \"id\": \"size\",\n                        \"name\": \"Size\",\n                        \"description\": \"T-Shirt size\",\n                        \"values\": [\n                            {\n                                \"id\": \"s\",\n                                \"name\": \"Size S\",\n                            },\n                            {\n                                \"id\": \"m\",\n                                \"name\": \"Size M\",\n                            },\n                            {\n                                \"id\": \"l\",\n                                \"name\": \"Size L\",\n                            }\n                        ]\n                    }\n                ]\n            },\n        ]\n    }\n]<\/code><\/pre>\n\n\n\n

However, that is \u2014 to my understanding \u2013 not truly RESTful anymore. Also, while the above example is still quite straightforward, things get ugly as nested objects include other nested objects, that include other nested objects, that\u2026 Quickly you get JSON responses of several tens or hundreds of kilobytes, although you\u2019re potentially only interested in two or three attributes. <\/p>\n\n\n\n

Moreover, on some pages of your shop you may be interested in all possible options (e.g. \u201esize\u201c) of a product, but not on others. Should your API define different view models<\/a> now and expose different endpoints? Or a single endpoints with query flags like ?expanded=true? Soon you might be catching yourself tailoring your API specifically to the needs of your client while neglecting REST conventions and a straightforward design.<\/p>\n\n\n\n

With GraphQL, things are different. Your API is a bit dumber and less opinionated now and does not deliver data in a fixed structure, according to a specified GQL query<\/a>, which looks a lot like JSON. The above example might look like this, now:<\/p>\n\n\n\n

Request\n-------\nPOST \/api\/graphql\/query\n\n{\n    \"query\": \"{\n        orders {\n            id\n            customerId\n            products {\n                name\n                price\n                options {\n                    name\n                }\n            }\n        }\n    }\"\n}\n\nResponse Body\n-------------\n{\n    \"data\": {\n        \"orders\": [\n            {\n                \"id\": 125,\n                \"customerId\": 8977,\n                \"products\": [\n                    {\n                        \"name\": \"Slim T-Shirt navy-blue\",\n                        \"price\": 17.90,\n                        \"options\": [\n                            {\n                                \"name\": \"Size\",\n                            }\n                        ]\n                    }\n                ]\n            }\n        ]\n    }\n}<\/code><\/pre>\n\n\n\n

This way, you get only the data you want. All your API has to know is how to fetch every piece of data. All your client has to know is how the data schema itself looks like.<\/p>\n\n\n\n

Try it out<\/h2>\n\n\n\n
\"\"<\/figure>\n\n\n\n

GitHub\u2019s official API offers GraphQL query endpoints. You can try it out using their GraphQL explorer<\/a>.<\/p>\n\n\n\n

GraphQL Basic
Since this article does not aim to be another introduction to GraphQL, you can read most of the basics about fields, data types, etc. in the
official docs<\/a>. However, it is worth mentioning that GraphQL supports three types of queries:<\/p>\n\n\n\n