Codegen configuration


The Apollo iOS Code Generation Engine is flexible and can be configured for different behaviors.

The configuration options for code generation are represented by the ApolloCodegenConfiguration struct.

When using the Codegen CLI, your configuration is represented by the apollo-codegen-configuration.json JSON file created by the CLI's init command.

When running code generation in your own Swift code, the configuration options are represented by the ApolloCodegenConfiguration struct.

Most of the configuration properties have defaults that provide a good starting point.

There are a number of base configuration properties, each representing a specific characteristic of the codegen engine:

Property NameDescription
schemaNamespaceNamespace used to scope the generated schema types.
inputSearch patterns that will be used to locate the schema and operation definition files.
outputLocation and structure of the generated files and modules.
optionsRules and options to customize the generated code.
experimentalFeaturesUsed to enable experimental features.
Note: These features could change at any time and are not guaranteed to always be available.
schemaDownloadConfiguration to fetch a GraphQL schema before generation.
operationManifestConfiguration to generate operation manifests for persisted queries

Schema namespace

schemaNamespace: String

This option defines the name of your schema module or namespace.

Along with your operation definitions, Apollo iOS generates a set of metadata objects that represent the types in your schema. All of these object are grouped within a namespace with the provided name.

  • If you are embedding your generated schema types within another target, this will be the name of a caseless namespace enum.

  • If you are including your schema types as a stand-alone target that can be imported by your other project targets, this will be the name of that target.

You can configure how you would like to include your schema types in your project using the output.schemaTypes.moduleType option.

File input

input: FileInput

The code generation engine requires a GraphQL schema and at least one operation to be able to generate Swift code. Read the introductory section on GraphQL source files for more information.

The properties to configure input are:

Property NameDescription
schemaSearchPathsAn array of path matching pattern strings used to find GraphQL schema files. Schema extension files can be included in these search paths.

Note: JSON format schema files must have the .json file extension.
operationSearchPathsAn array of path matching pattern strings used to find GraphQL operation files.
JSON
Swift
CLI Configuration JSON
1"input": {
2  "schemaSearchPaths": [
3    "**/*.graphqls"
4  ],
5  "operationSearchPaths": [
6    "**/*.graphql"
7  ]
8}

Search Path Patterns

Each file input property is a [String] search path array. Search paths can be used to search your project directory for files matching a glob pattern. You can use absolute or relative paths in path matching patterns. Relative paths will be based off the current working directory.

Each path matching pattern can include the following characters:

  • * matches everything but the directory separator (shallow), eg: *.graphql

  • ? matches any single character, eg: file-?.graphql

  • ** matches all subdirectories (deep), eg: **/*.graphql

  • ! excludes any match only if the pattern starts with a ! character, eg: !file.graphql

File output

output: FileOutput

The FileOutput options are used to configure which files are generated and their output locations.

The properties to configure output are:

Property NameDescription
schemaTypesLocation and structure of the generated schema types files.
operationsLocation and structure of the generated operation files such as queries, mutations, subscriptions, and fragments.
testMocksLocation and structure of the test mock operation object files.

If .none, test mocks will not be generated.
JSON
Swift
CLI Configuration JSON
1"output": {
2  "schemaTypes": {
3    "moduleType": {
4      "swiftPackageManager": {}
5    },
6    "path": "./generated/schema/"
7  },
8  "operations": {
9    "inSchemaModule": {}
10  },
11  "testMocks": {
12    "none": {}
13  }
14}

Schema types

output.schemaTypes: SchemaTypesFileOutput

Schema types are common to all generated operation models and are required for the generated Swift code to compile.

The properties to configure output.schemaTypes are:

Property NameDescription
pathA file path where the generated schema types should be output.

Relative to your project root
moduleTypeHow generated schema types will be linked to your project.

Module type

output.schemaTypes.moduleType: ModuleType

Use the ModuleType value to configure how your schema types are linked to your project. The Code Generation Engine uses this to determine the structure of the generated files, including import statements.

For single target applications, embeddedInTarget(name:) can be used.

For multi-module projects, it is recommended that the schema types be created in a separate module to help with separation of concerns. If using Swift Package Manager, the swiftPackageManager option can help automate module creation.

Note: This option must be set correctly for your project structure or generated code will fail to compile.

The possible values for moduleType are:

ValueDescription
embeddedInTarget(name:accessModifier:)Indicates that you would like to include the generated module directly in your application target.
swiftPackageManagerCreates a schema module as an SPM package that can be included in your project.
otherIndicates that you would like to manually define a schema module using a third party package manager (such as Cocoapods).

Embedded in target

ModuleType.embeddedInTarget(name: String, accessModifier: AccessModifier)

This option indicates that you would like to include the generated module directly in your application target.

The name parameter must specify the name of the target the schema types will be included in. This will be used to generate import statements for generated operations. Use the accessModifier parameter to control the visibility of the generated code.

No module will be created for the schema types. Instead, generated schema types will be enclosed in a caseless namespace enum.

When creating a single target application, this option allows you to include Apollo iOS's generated module directly in your application target.

Note: When using this module type, you are responsible for ensuring the generated files are linked to your application target.

JSON
Swift
CLI Configuration JSON
1"output": {
2  "schemaTypes": {
3    "moduleType": {
4      "embeddedInTarget": {
5        "name": "MyApplicationTarget",
6        "accessModifier": "internal"
7      }
8    },
9    "path": "./generated/schema/"
10  }
11}

Swift package manager

ModuleType.swiftPackageManager

This option automates the creation of an SPM package for your schema types. This generates a Package.swift file that is suitable for linking the generated schema types files to your project using Swift Package Manager.

The schema types will be contained in a stand-alone module with the schemaNamespace provided. Other targets in your application that contain generated operation models must have a dependency on this target.

For multi-module projects using Swift Package Manager, this is the recommended configuration option.

Including schema types in your own Package.swift file:

This option generates an SPM package with its own Package.swift file. This is ideal if you want to share your schema module across multiple projects or using Xcode's Package Dependency GUI.

If you would like to include your schema module as a target in your own Package.swift file, you can define a target with the name and path of the generated files in your Package.swift file.

JSON
Swift
CLI Configuration JSON
1"output": {
2  "schemaTypes": {
3    "moduleType": {
4      "swiftPackageManager": {}
5    },
6    "path": "./generated/schema/"
7  }
8}

Other schema module types

ModuleType.other

This value should be used when you would like to define a schema module using another package management system (such as CocoaPods), or you want more control over the generated package than what ModuleType.swiftPackageManager allows, or manually creating your own targets or modules in another way.

ModuleType.other indicates to the Code Generation Engine that your schema types will be contained in their own target, rather than embedded in your application target. This affects the import statements in your generated operation definition files.

Using this option, you are required to create a target, or module, for your schema module using your preferred package manager.

Note: You must specify the name of the target, or module, you created in the schemaNamespace property of your configuration. This will be used for import statements as well as to fully qualify the referenced types in generated operation files.

JSON
Swift
CLI Configuration JSON
1"output": {
2  "schemaTypes": {
3    "moduleType": {
4      "other": {}
5    },
6    "path": "./generated/schema/"
7  }
8}

Operations

Operation files are generated from all the GraphQL operation definitions matched by your configuration's operationSearchPaths. Each operation (query, mutation, or subscription) and fragment definition will be created in a separate file.

To learn more about GraphQL operations, check out Defining operations.

The output.operations property value determines the location of the generated operation files:

ValueDescription
inSchemaModuleOperation models will be included in the schema types module.
relative(subpath:accessModifier:)Operation models will be output relative to their defining .graphql files.
absolute(path:accessModifier:)All operation object files will be located in the specified path.

Operations in the schema module

OperationsFileOutput.inSchemaModule

This option includes the generated operation models in the same module as your schema types.

This means the output location or your operation models is determined by the output.schemaTypes.path option. When using this option the directory of your schema module will include a Schema folder for your schema types, as well as folders for your operations, fragments, and local cache mutations.

When using this option, generated operation models are expected to be included in the same target as the schema types. Therefore they will not include import statements to import the schema module.

Relative operations output

OperationsFileOutput.relative(subpath: String?, accessModifier: AccessModifier)

This option outputs your generated operation models relative to their GraphQL definition (.graphql files).

Using relative operation outputs, you have complete control over where your operation definitions are generated. It is common practice to co-locate your operation and fragment models with the parts of your project that will use them.

An optional subpath parameter can be provided to generate operation models in a subfolder that will be created within the directory of their defining GraphQL definition file. If no subpath is specified then all operation files will be generated alongside thier GraphQL definition files. Use the accessModifier property to control the visibility of the generated code.

Operation Models in a multi-module project:

If your project constists of multiple modules you can use relative operation output, to generate operation models into directories that are part of different modules in your project. In order to generate relative operation models for a multi-module project, all of your operation models should be generated at the same time. This means the Code Generation Engine should be run in a context that has access to the source files of all of your modules.

After generating your operation models ensure that:

  • All modules containing generated operation models are linked to the target containing your schema types.

  • All fragments referenced by your operation models are either:

    • Included in the same target as the referencing operation; or

    • Included in the schema module directly

In the future, we plan to allow you to include fragments in other modules and share them between multiple modules in your project.

Absolute operations output

OperationsFileOutput.absolute(path: String, accessModifier: AccessModifier)

This option outputs all of your generated operation models in a single directory.

Specify the directory for your operation models using the path parameter. This is resolved as a relative path from the directory containing your apollo-codegen-config.json file when using the CLI. Use the accessModifier property to control the visibility of the generated code.

Test mocks

output.testMocks: TestMockFileOutput

Test mock objects can be created for your operation models, to configure whether test mocks are generated and how they are added to your project, use this option.

To learn more about using test mocks to mock your operation models, see the Test mocks documentation.

The output.testMocks option can be configured with the following values:

ValueDescription
noneTest mocks will not be generated.
swiftPackage(targetName:)Test mock files will be generated and included in a target defined in an SPM package.
absolute(path:accessModifier:)Test mock files will be generated at the specified path.

Test mocks in a Swift Package

TestMockFileOutput.swiftPackage(targetName: String?)

This option generates test mock files and defines a target in the schema modules generated Package.swift file that is suitable for linking the test mock files to your test target using Swift Package Manager.

The name of the test mock target can be specified with the targetName parameter. If no targetName is provided, the target name defaults to "${schemaNamespace}TestMocks".

Note: Using this option requires your output.schemaTypes.moduleType to be .swiftPackageManager. If this option is provided without the .swiftPackageManager module type, code generation will fail.

Absolute test mocks output

TestMockFileOutput.absolute(path: String, accessModifier: AccessModifier)

This option outputs all of your generated test mocks in a single directory.

Specify the directory for your test mocks using the path parameter. This is resolved as a relative path from the directory containing your apollo-codegen-config.json file when using the CLI. Use the accessModifier property to control the visibility of the generated code.

Note:

  • When using this option, you are responsible for ensuring the generated test mocks are linked to your test target.

  • Test mocks generated this way may also be manually embedded in a test utility module that is imported by your test target.

  • Test mocks are required to be in a target or module that is separate from the schema module and will always include import statements linking the schema module.

Output options

options: OutputOptions

The code generation engine supports a number of configuration options to change the behaviour of the generator and tailor the generated Swift code to your specific needs.

The top-level properties are:

Property NameDescription
additionalInflectionRulesAny non-default rules for pluralization or singularization of type names.
deprecatedEnumCasesAnnotate generated Swift enums with the Swift @available attribute for GraphQL enum cases annotated with the built-in @deprecated directive.
schemaDocumentationInclude or exclude schema documentation in the generated files.
selectionSetInitializersGenerate initializers for your generated selection set models.
operationDocumentFormatHow to generate the operation documents for your generated operations. This can be used to generate operation identifiers for use with a server that supports Persisted Queries or Automatic Persisted Queries
cocoapodsCompatibleImportStatementsGenerate import statements that are compatible with including Apollo via Cocoapods.
warningsOnDeprecatedUsageAnnotate generated Swift code with the Swift @available attribute and @deprecated argument for parts of the GraphQL schema annotated with the built-in @deprecated directive.
conversionStrategiesRules for how to convert the names of values from the schema in generated code.
pruneGeneratedFilesWhether unused generated files will be automatically deleted.
markOperationDefinitionsAsFinalWhether generated GraphQL operation and local cache mutation class types will be marked as final.
schemaCustomizationCustomization options to be applied to the schema during code generation.
JSON
Swift
CLI Configuration JSON
1"options": {
2  "additionalInflectionRules": [{
3    "pluralization": {
4      "replacementRegex": "animals",
5      "singularRegex": "animal"
6    }
7  }],
8  "deprecatedEnumCases": "include",
9  "schemaDocumentation": "include",
10  "selectionSetInitializers" : {
11    "operations": false,
12    "namedFragments": false,
13    "definitionsNamed": [
14      "MyOperation",
15      "MyFragment"
16    ]
17  },
18  "operationDocumentFormat" : ["definition", "operationId"],
19  "cocoapodsCompatibleImportStatements": false,
20  "warningsOnDeprecatedUsage": "include",
21  "conversionStrategies": {
22    "enumCases": "camelCase",
23    "fieldAccessors": "default",
24    "inputObjects": "camelCase"
25  },
26  "pruneGeneratedFiles": true,
27  "markOperationDefinitionsAsFinal": true,
28  "schemaCustomization" : {
29    "customTypeNames" : {
30      "MyEnum" : {
31        "enum" : {
32          "cases" : {
33            "MyCase" : "CustomCase"
34          },
35          "name" : "CustomEnum"
36        }
37      },
38      "MyObject" : "CustomAnimal",
39      "MyInputObject" : {
40        "inputObject" : {
41          "fields" : {
42            "myField" : "customField"
43          },
44          "name" : "CustomInputObject"
45        }
46      }
47    }
48  }
49}

Selection Set Initializers

You can get initializers for your generated selection sets by using the selectionSetInitializers option.

Manually initialized selection sets can be used for a number of purposes, including:

  • Adding custom data to the normalized cache

  • Setting up fixture data for SwiftUI previews or loading states

  • An alternative to Test Mocks for unit testing

You can configure initializers to be generated for all operations, all named fragments, or only select operations or named fragments instead. Initializers are always generated for local cache mutations. SelectionSetInitializers functions like an OptionSet, allowing you to combine multiple different instances together to indicate all the types you would like to generate initializers for.

To learn more about how to use Selection Set Initializers, check out Using Selection Set Initializers.

JSON
Swift
CLI Configuration JSON
1"options": {
2  "selectionSetInitializers" : {
3    "operations": false
4    "namedFragments" : false,
5    "definitionsNamed": [
6      "MyOperation",
7      "MyFragment"
8    ]
9  },
10}

Schema Customization

Custom Type Names

Schema types can have their names used in Swift code customized by using the customTypeNames option under schemaCustomization to provide new names for the types which you wish to rename in Swift. This does not affect your schema directly, or network requests sent to your server, only the type names used by you in your Swift code. The customTypeNames option accepts a Dictionary which maps schema type names given as a String to a CustomSchemaTypeName enum case with associated values for how to customize the given schema type.

You can customize the name of the following schema types:

  • Custom Scalar

  • Enum (including individual case names)

  • Input Object (including individual field names)

  • Interface

  • Object

  • Union

The CustomSchemaTypeName enum contains the following possible cases:

CaseDescriptions
.type(name:)This case can be used to customize the name of any type in your schema by supplying a String to the name parameter representing the desired new name.
.enum(name:cases:)This case must be used when you want to customize the cases of an enum type. You can optionally supply a String to the name parameter to customize the name of the enum itself, and supply a [String: String] dictionary to the cases parameter to customize any cases you desire.
.inputObject(name:fields:)This case must be used when you want to customize the fields of an Input Object type. You can optionally supply a String to the name parameter to customize the name of the Input Object itself, and supply a [String: String] dictionary to the fields parameter to customize any fields you desire.
JSON
Swift
CLI Configuration JSON
1"options": {
2  "schemaCustomization" : {
3    "customTypeNames" : {
4      "MyEnum" : {
5        "enum" : {
6          "cases" : {
7            "MyCase" : "CustomCase"
8          },
9          "name" : "CustomEnum"
10        }
11      },
12      "MyObject" : "CustomAnimal",
13      "MyInputObject" : {
14        "inputObject" : {
15          "fields" : {
16            "myField" : "customField"
17          },
18          "name" : "CustomInputObject"
19        }
20      }
21    }
22  }
23}

Experimental features

experimentalFeatures: ExperimentalFeatures

The code generation engine supports some behaviors where the affect on the generated code is considered experimental. An example of this is a specification of the GraphQL schema that is not yet formalized and undergoing change as the proposal advances.

Note: These features could change at any time and are not guaranteed to always be available.

The current supported experimental features are:

Valueescription
fieldMergingDetermines which merged fields and named fragment accessors are generated. Defaults to .all.
legacySafelistingCompatibleOperationsIf enabled, the generated operations will be transformed using a method that attempts to maintain compatibility with the legacy behavior from apollo-tooling for registering persisted operation to a safelist.

Note: Safelisting queries is a deprecated feature of Apollo Server that has reduced support for legacy use cases. This option may not work as intended in all situations.
JSON
Swift
CLI Configuration JSON
1"experimentalFeatures": {
2  "fieldMerging": [
3    "all"
4  ],
5  "legacySafelistingCompatibleOperations": false
6}

Schema download configuration

schemaDownload: ApolloSchemaDownloadConfiguration

An optional step in the code generation process is to fetch a GraphQL schema from a remote server. This step ensures that you always have an up-to-date schema on which to base your operations and it eliminates the need to manually download the schema outside of the automated process.

The properties to configure the schema download are:

Property NameDescription
downloadMethodHow to download the schema.
downloadTimeoutThe maximum time (in seconds) to wait before indicating that the download timed out.
headersAny additional headers to include when retrieving your schema. This is useful when the schema download requires authentication.
outputPathThe local path where the downloaded schema should be written to.

Download method

There are two supported sources for fetching a GraphQL schema:

1. Apollo server registry

The Apollo schema registry serves as a central hub for managing your graph.

The properties you will need to configure are:

Property NameDescription
apiKeyAPI key to use when retrieving your schema from the Apollo Registry.
graphIDIdentifier of the graph to fetch. Can be found in Apollo Studio.
variantVariant of the graph in the registry.
JSON
Swift
CLI Configuration JSON
1"schemaDownload": {
2  "downloadMethod": {
3    "apolloRegistry": {
4      "_0": {
5        "graphID": "your-graphid",
6        "apiKey": "your-api-key",
7        "variant": "current"
8      }
9    }
10  },
11  "downloadTimeout": 60,
12  "headers": {
13    "Accept-Encoding" : "gzip",
14    "Authorization" : "Bearer <token>"
15  },
16  "outputPath": "./graphql/"
17}

2. GraphQL introspection

A GraphQL service supports introspection over its schema.

Note: Many production servers disable introspection for security reasons. If your introspection query is failing check that it is not disabled.

The properties you will need to configure are:

Property NameDescription
endpointURLURL of the GraphQL introspection service.
httpMethodHTTP request method.
outputFormatOutput format for the downloaded schema.
includeDeprecatedInputValuesSpecify whether input values annotated with the built-in @deprecated directive should be included in the fetched schema.
JSON
Swift
CLI Configuration JSON
1"schemaDownload": {
2  "downloadMethod": {
3    "introspection": {
4      "endpointURL": "https://server.com",
5      "httpMethod": {
6        "POST": {}
7      },
8      "includeDeprecatedInputValues": false,
9      "outputFormat": "SDL"
10    }
11  },
12  "downloadTimeout": 60,
13  "headers": [],
14  "outputPath": "./graphql/"
15}

For more details, see the section on downloading a schema.

Operation Manifest Configuration

operationManifest: OperationManifestConfiguration

Optional settings used to configure generation of the operation identifier manifest for use with Persisted Queries.

Property NameDescription
pathLocal path where the generated operation manifest file should be written.
versionThe version format to use when generating the operation manifest.
generateManifestOnCodeGenerationWhether or not the operation manifest should be generated every time code generation is run. Defaults to false.
JSON
Swift
CLI Configuration JSON
1"operationManifest" : {
2  "generateManifestOnCodeGeneration" : false,
3  "path" : "/operation/identifiers/path",
4  "version" : "persistedQueries"
5}

Full Codegen Configuration Example

Below is an example that illustrates an apollo-codegen-config.json where every available option is configured in some way to show its usage and formatting:

JSON
apollo-codegen-config.json
1{
2  "schemaNamespace" : "MySchema",
3  "schemaDownload": {
4    "downloadMethod": {
5        "introspection": {
6            "endpointURL": "https://server.com",
7            "httpMethod": {
8                "POST": {}
9            },
10            "includeDeprecatedInputValues": false,
11            "outputFormat": "SDL"
12        }
13    },
14    "downloadTimeout": 60,
15    "headers": [],
16    "outputPath": "./graphql/"
17  },
18  "experimentalFeatures" : {
19    "fieldMerging": [
20        "all"
21    ],
22    "legacySafelistingCompatibleOperations" : true
23  },
24  "operationManifest" : {
25    "generateManifestOnCodeGeneration" : false,
26    "path" : "/operation/identifiers/path",
27    "version" : "persistedQueries"
28  },
29  "input" : {
30    "operationSearchPaths" : [
31      "/search/path/**/*.graphql"
32    ],
33    "schemaSearchPaths" : [
34      "/path/to/schema.graphqls"
35    ]
36  },
37  "output" : {
38    "operations" : {
39      "absolute" : {
40        "accessModifier" : "internal",
41        "path" : "/absolute/path"
42      }
43    },
44    "schemaTypes" : {
45      "moduleType" : {
46        "embeddedInTarget" : {
47          "accessModifier" : "public",
48          "name" : "SomeTarget"
49        }
50      },
51      "path" : "/output/path"
52    },
53    "testMocks" : {
54      "swiftPackage" : {
55        "targetName" : "SchemaTestMocks"
56      }
57    }
58  },
59  "options" : {
60    "additionalInflectionRules" : [
61      {
62        "pluralization" : {
63          "replacementRegex" : "animals",
64          "singularRegex" : "animal"
65        }
66      }
67    ],
68    "cocoapodsCompatibleImportStatements" : true,
69    "conversionStrategies" : {
70      "enumCases" : "none",
71      "fieldAccessors" : "camelCase",
72      "inputObjects": "camelCase"
73    },
74    "deprecatedEnumCases" : "exclude",
75    "operationDocumentFormat" : [
76      "definition"
77    ],
78    "pruneGeneratedFiles" : false,
79    "schemaDocumentation" : "exclude",
80    "selectionSetInitializers" : {
81      "operations": false,
82      "namedFragments" : false,
83      "definitionsNamed": [
84        "MyOperation",
85        "MyFragment"
86      ]
87    },
88    "warningsOnDeprecatedUsage" : "exclude",
89    "operationDocumentFormat" : ["definition", "operationId"],
90    "markOperationDefinitionsAsFinal": true
91  }
92}
Feedback

Edit on GitHub

Forums