Why SwiftGraphQL?

There are two big reasons why you should choose SwiftGraphQL for your project. The first section outlines why you should consider using SwiftGraphQL in your project and the second one explains why we think it’s the best Swift GraphQL client.

Simply put, it’s going to save you and your team lots of time. There’s a high chance that you are currently writing most of your GraphQL queries by hand. If not, there’s probably some part of the link between backend and your frontend that you have to do manually and isn’t computer checked.

As you may know well, manual work is error-prone. This library is an end to end type-safe and spec-compliant. This way, you can be confident that once your app compiles, your queries are going to work.

Structural vs Nominal Types

To understand why we developed SwiftGraphQL it’s essential to understand the difference between structural and nominal types.

The easiest way to understand the difference is to see an example. In TypeScript, for example, you can write

type Foo = {
  a: number
  b: string
}

type Bar = {
  a: number
  b: string
}

let foo: Foo = { a: 92, b: 'hey' }
let bar: Bar = { a: 42, b: 'bye' }

foo = bar // okay.

while in Swift, for example, you can’t write

struct Foo {
	var a: Int
	var b: String
}

struct Bar {
	var a: Int
	var b: String
}

var foo = Foo(a: 92, b: "hey")
var bar = Bar(a: 42, b: "bye")

foo = bar // error!

The reason for the difference is that Swift compares structs nominally (i.e. “using their name”) while TypeScript compares their structure. Both Foo and Bar types contain the same values and are therfore the same type in TypeScript.

This example is not perfect because switching types for classes would result in the same behaviour in TypeScript as in Swift, but you’ll see the point soon.

Most widely used SwiftGraphQL alternative is Apollo iOS - a fantastic client by the way! Apollo iOS works by generating Swift types from your GraphQL queries. Consider the following schema and query;

# Schema
type Query {
  """
  Everyone you can find.
  """
  people: [Human!]!
}

type Human {
  id: ID!
  name: String!
  age: Int!
}

type Mutation {
  """
  Creates a new user with your name.
  """
  join(name: String!, age: Int!): Human!
}

# Queries
query Friends {
  people {
    id
    name
    age
  }
}

mutation Join {
  join(name: "Matic", age: 21) {
    id
    name
    age
  }
}

Apollo iOS takes your schema and your query and generates a Swift representation of your query.

Unfortunatelly, however, it represents the human type returned by people query as a different structure than the one returned by the join mutation. This behaviour closely matches how Apollo client works in TypeScript except there it works as expected.

If you want to map your GraphQL types to the application model (like we did) this becomes very cumbersome. That’s why we created SwiftGraphQL. SwiftGraphQL lets you write a “fragment” for each type and reuse it everywhere. This way, we make sure the same GraphQL types always result in same Swift structures.

NOTE: This might not be a problem if you only care about reading the returned values and don’t have a complex data model.