Infrastructure as Code Best Practices with Terraform for DevOps
João Victor Alhadas | Dec 17, 2024
Integrating apps and servers is not an easy task, we all know that. Even with great tools like Alamofire and Retrofit there are still a lot of things to take care of in the app side: different endpoints, encoding / decoding JSON strings, API versions, data consistency and so on…
Recently I have worked in a project with server integration and we had the opportunity to choose new technologies to work with and to try to avoid some of these problems. The choice was a GraphQL server and in the app side the Apollo framework.
GraphQL is a query language created by Facebook that is being used in its apps since 2012. The reasons why we chose to use it are:
Here is a small example of a GraphQL query:
query GetPostById { Post(id: "cj6py4hi614bx01580y11k0go") { title content } } And its response:
{ "data": { "Post": { "title": "International Space Station", "content": "Its first component launched into orbit in 1998." } } }
On the client side, there are different situations that the application has to deal with. However, since GraphQL runs over an HTTP connection and its response is a JSON string, the problems are pretty much the same as REST. But actually, here starts all the magic.
Apollo is a very nice framework. It provides everything necessary to create requests to the server. It also lies on a GraphQL server schema to make all the parsing, normalization and caching of data a piece of cake. Here are the main reasons to choose it:
Next I will show how simple it is to configure Apollo and how easy it is to make queries and use its cache. Also, you’ll see how it automatically creates typed objects with all data you just fetched.
For example purposes on this post I will use the iOS version in Swift.
Setting up Apollo in a project requires a little configuration, but it’s very simple to do it. For iOS it requires basically the following steps:
This is the initial setup to start making queries and mutations on your iOS app. All the setup steps are detailed in Apollo documentation.
With everything up and running we can start performing fetches. To do that you simply create GraphQL queries in a .graphql file. You can create as many files as you want. For this example I will be using a very simple API with posts and comments. There is a link for the sample project in the end of this post.
Ok, now let’s see what Apollo can do!
First of all we create a .graphql file with the GraphQL query to fetch all posts:
query AllPosts { allPosts { ...Post } }
fragment PostObject on Post { title content }
If you build the project now you will see that API.swift file have now a bunch of code. In this code there are swift methods to perform the queries and structs that represent the data returned by the server.
The last thing we need before performing a fetch query is the client that accesses the server. To do this we create an instance of Apollo Client. I use a singleton with a unique apollo client to keep a unique cache and use in all code. But let’s keep it simple for now.
let url = "https://my-amazing-api.com/graphql" let apolloClient = ApolloClient(url: url)
Now we use the auto generated query object as parameter to the fetch method in the client and a callback to deal with the result. This result will already be cached.
apolloClient.fetch(query: query) { result, error in let posts: [PostObject]? = result?.data?.allPosts.map { return $0.fragments.postObject } self.posts = posts ?? [] }
As you can see in the .graphql file I used a fragment called PostObject. Apollo converts this fragment into a struct. The response from server will be mapped into this structs and you can use them directly in your UI code and other parts of the project.
You can also pass to the fetch method a parameter to change the cache policy. There are currently four options:
Using these options appropriately can reduce access to network and improve UI response. In the sample project for example I fetch all posts in the list screen. And in the details screen I just used the cached data, so I avoid another request and I guarantee that my fetched data always come from the same place, avoiding inconsistency in the app.
This is just a small example of what Apollo can do. In the sample project there are also examples of watching queries that helps us to keep UI always updated with the last cache version and also a mutation to perform changes in server data.
My experience with Apollo started with a few concerns regarding this whole new concept of fetching and manipulating data along with the server. But after a few months using it I can say that I would always choose Apollo for my future projects.
The Apollo project is new and there are already a lot of users. There are a lot of things to come and you can, of course, contribute as its open source. You can check the example code in this GitHub repository.
Here are some resources that might help too:
I’m a mobile developer who loves giving life to smart and beautiful apps. I also appreciate a good walk at the beach, cold beer, burger and fries, good music and talk about life, the universe and everything else.