From iOS to Server-side Swift
I’ve been working on various iOS apps for over a decade. In this time, I did also experiment with other projects, including an Objective-C based http server. After the advent of Swift, I’ve read glimpses of something called Vapor. I was curious what it was.
And I finally got the time to look into it. Discussing it with my friend Klemen, he pointed out I could also take a look at GraphQL while I’m at it.
I thereby set out on an adventure, use Vapor, GraphQL and Composable Architecture for the client, to build a complete project, displaying a simple list of stars and their planets.
On the Server
For the sake of simplicity I decided to use an in memory sqlite database behind Fluent. I like how Fluent abstracts away interfacing with the database, so in case I wanted to change my backing db, I wouldn’t have to change anything in my source code. In order to support GraphQL, I decided to adopt GraphQLKit and GraphiQLVapor. This allowed me to get something working really quickly.
The two main points for supporting GraphQL in your Vapor app for me are:
- Create your resolver
- Create the schema
Resolver is the object GraphQLVapor will ask to perform queries or mutations. I put all my database access code in there.
In the sample above, I wanted to use async/await from Fluent, but wasn’t sure how to couple it with GraphQLKit’s requests, which is why I have it wrapped up in an EventLoopGroups future.
Schema is a description for GraphQL, of what entities are available and what queries or mutations can be performed.
Once this is done, tell the Vapor application to register the newly created schema.
With the above code, we have a working GraphQL endpoint in our app. We can already make queries or perform mutations.
To enable browsing the GraphQL implementation directly on the server, I used GraphiQL-Vapor, just adding the following line after registering the GraphQL schema.
With this, I can make queries and mutations directly at localhost:8080/explore
On the Client
Googling for an iOS GraphQL client lead me straight to Apollo. Once added as a dependency to the client project, I needed to tell Apollo where to get the schema and what operations can be performed. This is done in a codegen-config.json
file.
I had to specify the server location and operations that I want to do in order for Apollo to generate objects I could then use in my client app.
After that it was time to structure the application so it can display and create Stars and Planets.
I decided to introduce model objects separately in the Client domain. Even though this essentially duplicates models, it allows me to stay flexible in the future in case I would want to swap Apollo for a different GraphQL client implementation. It also frees me from coupling the business logic with the network layer.
Conclusion
I am very excited about my first step into the world of server-side swift. There is certainly a lot more for me to explore here. Vapor is built on top of SwiftNIO and there are other frameworks similar to Vapor worth exploring as well.
The main take-away for me here is the knowledge, that I can now provide backend services for any of my projects, without leaving the world of Swift.
Feel free to take a look around the project on my GitHub
References:
GraphQL Vapor Template where I figured out how to set up the schema.
Getting Started with Apollo where I figured how to get Apollo client up and running.
Fluent where I learned how to interface with the database.