Skip to content

NoDevOrg/GraphQLTools

Repository files navigation

GraphQLTools

GraphQL Tools for Server Side Swift.

Getting Started

While it will be helpful to have created a GraphQL API with Graphiti before, it is not required in order to use the codegen CLI or plugin. Graphiti is a library for writing GraphQL APIs where the schema is defined in code. However some people/teams prefer to write a GraphQL schema first in a .graphqls file before implementing the server and client. This package provides a swift CLI and swift package plugin to generate Graphiti based code from a schema file.

Installation

Add GraphQL Tools to your Package.swift

let package = Package(
    dependencies: [
        .package(url: "https://github.com/NoDevOrg/GraphQLTools", from: "1.0.0"),
    ]
)

CLI

If you'd like to use the CLI directly you can run swift run graphql-schema-code-gen-cli. It will print out the options you'll need in order to generate Graphiti schema code.

A basic invocation of the command is swift run graphql-schema-code-gen-cli --schema-path ./path/to/schema.graphqls --output-path ./path/to/GeneratedSchema.swift

Plugin

If you'd like to use the plugin then you'll need to include a file named graphql-schema-codegen-config.json in your Source/Target folder. The contents of the file should be:

{
  "invocations": [
    {
      "schemaFiles": ["Path/To/Schema.graphqls"]
    }
  ]
}

Then in your Package.swift you'll need to add:

let package = Package(name: "PackageName", targets: [
    .executableTarget(
        name: "ServiceName",
        dependencies: [
            .product(name: "Graphiti", package: "Graphiti")
        ],
        resources: [
            .copy("Path/To/Schemas"),
            .copy("graphql-schema-codegen-config.json"),
        ],
        plugins: [
            .plugin(name: "GraphQLSchemaCodeGenPlugin", package: "GraphQLTools")
        ]
    ),
])

Now when you run swift build or press Build in Xcode the generated code will be generated and a part of your build.

Integration

While the code generated by the CLI or plugin is helpful it is not the full story. You still need to integrate Graphiti into a web framework such as Vapor. Pioneer is a great framework that can accept a Graphiti schema and integrate it into Vapor.You can check out the Examples folder for examples on how to write resolvers for queries, mutations, and subscriptions.

At minimum you'll need to define a Resolver struct that implementes the generated protocol.

import Graphiti

struct Resolver: GeneratedSchema.GeneratedResolver {
    typealias ContextType = NoContext
}

Then you can use that with Vapor/Pioneer to expose a GraphQL API.

import Graphiti
import Pioneer
import Vapor

let application = try Application(.detect())

let pioneer = Pioneer(
    schema: try GeneratedSchema.schema(),
    resolver: Resolver()
)

application.middleware.use(
    pioneer.vaporMiddleware(
        context: { _, _ in
            NoContext()
        },
        websocketContext: { _, _, _ in
            NoContext()
        }
    )
)

defer { application.shutdown() }
try application.run()

You can also define your own Context type if you need to. A context is created for each request and it usually contains properties like header values, references to Vapor's request. More information on Vapor can be found here.