GraphQL Tools for Server Side Swift.
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.
Add GraphQL Tools to your Package.swift
let package = Package(
dependencies: [
.package(url: "https://github.com/NoDevOrg/GraphQLTools", from: "1.0.0"),
]
)
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
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.
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.