Docs
Launch GraphOS Studio

Project configuration

Structuring a GraphQL application with the Apollo iOS SDK


Apollo iOS 1.0 can support complex applications composed of multiple modules and monolithic application targets.

The code generation engine and modularized structure of the Apollo iOS SDK provide flexible configuration options, enabling you to structure your project as you like.

This article covers the models generated by Apollo iOS, the modules that compose the Apollo iOS SDK, and how to structure these components in your project.

Generated models

Apollo iOS generates the following groups of files for you:

  • Operation models: Models for the queries, s, s, and s defined in your GraphQL files.
  • Schema types: Your GraphQL 's shared types and metadata (e.g., objects, enums, input objects).
  • Test mocks: Test mock objects for your types, which you can use to create models in your tests.

Operation models

Apollo iOS generates operation models from the files where you define your GraphQL s (i.e., queries, s, s, and s).

models are classes that represent your GraphQL operations, which you can then use to make GraphQL requests (via ApolloClient).

Each model includes a set of type-safe response model objects, representing that operation's result. When ApolloClient successfully executes a GraphQL request, it returns an instance of the corresponding response model for the executed .

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

Schema types

GraphQL s use a type system to define the shape of your available data. GraphQL s (and your generated operation models) depend on a schema to know how to shape their operations to access a server's data.

Apollo iOS generates a collection of types that provide the properties and metadata about each type in your GraphQL (i.e., objects, interfaces, unions, enums, input objects, etc.). Your generated operation models reference these shared types to provide type information without duplicating code.

Test mocks

Apollo iOS enables you to generate test mock objects that you can use in your test targets. These mocks enable you to create models for your tests.

For more details, see Test Mocks.

Structuring your project

When including Apollo iOS in a new project, deciding how to structure your project is an essential first step. A large part of this step is determining where your generated GraphQL models fit.

You can include your GraphQL models in your main application target, spread them across many modules, or expose them as an independent module that multiple applications can use. Depending on the needs and constraints of your project, you'll configure the code generation engine and link to the Apollo iOS libraries differently.

Below, we cover the three primary decisions you'll need to make about your project structure.

Single target vs multi-module

1. Does your project consist of a single application target or multiple modules?

Depending on the size and complexity of your project, it might be built as a single monolithic application target or be composed of multiple modules.

For a monolithic application, you can link your application target to the Apollo library. You can also optionally link to ApolloSQLite and/or ApolloWebSocket to enable their functionality.

For more information about the libraries that make up the Apollo iOS SDK, see the Apollo iOS SDK.

To include the Apollo iOS SDK in a project with multiple modules:

  1. Link Apollo to the modules configuring or using the networking and caching APIs.
    • Optionally, link ApolloSQLite and/or ApolloWebSocket to the module that sets up your ApolloClient to enable them.
  2. Link ApolloAPI to the modules that only include generated models.

Additionally, you can optionally link ApolloTestSupport to your unit test target to create mocks of your generated models.

⚠️ Do not link ApolloCodegenLib to your application targets.

ApolloCodegenLib only supports macOS, and you should only link it to development tools that want to use the Apollo code generation engine.

Schema types module

2. How do you want to include your generated schema types?

You can include generated types in your project by embedding them directly in your application target or as a separate module. You can configure this using the output.schemaTypes property in your codegen configuration.

When setting up codegen for the first time, you'll need to specify a location path for the generated module and the moduleType. The moduleType property configures how the code generation engine links generated types in your project.

For most projects, we recommend creating a separate module. This enables you to share your generated models across modules as your project grows. For simple single-target applications, you can embed your schema types directly in your target.

Creating a schema module

You can link a module to every module that includes or consumes your generated models.

The code generation engine can automate the creation of modules for the Swift Package Manager. The code generation engine is also flexible enough to support manual configuration for projects that require customized dependencies.

Use the .swiftPackageManager or .other options to generate a types module.

Most dependency managers (e.g., SPM and Cocoapods) can automatically include your generated files in the module's directory. This means that when generated files are added or removed from the generated module, they are linked to your project automatically.

Embedded in your application

You can also include types directly in a target that you created.

To do this, use ModuleType.embeddedInTarget(name: String) as the value of the output.schemaTypes.moduleType property. The generated types are scoped within a caseless enum used as a namespace to prevent conflicts with types you may already have defined in your target.

If you require more control over your types you can use the ModuleType.other value. This gives you full control over the module and your choice of dependency manager.

These options makes you responsible for manually adding generated files to your chosen target or module. When the code generation engine creates or removes files, you'll need to manually add or remove them from the project navigator.

Operation model generation

3. Where should your generated operation models live?

Finally, choose how you want to use models in your project. You can configure this using the output.operations property in your codegen configuration.

The only requirements are that your models have access to your types and the ApolloAPI target to compile successfully.

Generally, you'll decide between two options: confined models or shared models.

Confined models

If you want to organize your generated models by specific feature areas or modules, use the OperationsFileOutput.relative(subpath: String?) value for the output.operations property. The code generation engine now generates your models relative to the .graphql files that define them.

This option gives you the most flexibility and control over your models. You can generate them anywhere in your project structure by organizing your .graphql definitions.

With relative paths, you can:

  • Co-locate models alongside the feature code using them
  • Include models in different modules across your project
  • Organize models based on feature area
  • Or use any other structure your project needs

When including your models in a multi-module project, ensure that any modules that include your operation models link to both your schema types module and the ApolloAPI library.

Shared models

You can also share your generated models across modules in your project. You can do this by including them within the shared types module or by manually including them in another shared module.

Bundling within a shared schema type module

For most small projects, including your models within the shared type module is the most straightforward way to share them. With this structure, your operation models are in a sub-folder of the schema types module directory.

You can do this using the .inSchemaModule option for the output.operations property:

  • If you have a schema module, the codegen engine includes your s in that module, which you can then import into your project's other modules.
  • If you are embedding your schema in another target, the codegen engine includes your s in the generated namespace in your application target.
Absolute path

You can also generate your models into a single directory using the .absolute(path:) option. Then, you can manually include this directory in your project however you see fit.

If you choose to generate the models to an absolute path, you are responsible for linking the generated files to the rest of your project. You must ensure that any targets included by your operation models link to both your types module and the ApolloAPI library.

Supporting other configurations

Above, we've shared the most common examples of modular architecture, but there are many alternative configurations we haven't covered.

Apollo iOS has different options to support flexible configurations of your types and models. We recommend familiarizing yourself with Apollo iOS's codegen configuration to find a combination that best suits your project needs.

Apollo iOS SDK components

For Cocoapods users:

Cocoapods combines subspecs into a single target. This means that:

Libraries that compose the Apollo iOS package:

DescriptionUsage

Apollo

The core Apollo client library.

Includes the networking and caching APIs, including ApolloClient and ApolloStore.

Any targets that need to access these core components directly should be linked against Apollo.

ApolloAPI

Includes the common components that generated models use for your project.

Any targets that include your generated models should be linked to ApolloAPI.

The Apollo library has a dependency on this target, so any target that links to Apollo doesn't need to link to ApolloAPI directly.

Because generated models export the ApolloAPI library's interface, targets that consume generated models but don't contain them don't need to link to ApolloAPI directly.

ApolloSQLite

Provides a NormalizedCache implementation backed by a SQLite database.

Use this library if you'd like to persist cache data across application lifecycles. This library only needs to be linked to your targets that configure the SQLiteNormalizedCache and pass it to the ApolloStore.

For more information on setting up a persistent SQLite cache, seeSQLiteNormalizedCache.

ApolloWebSocket

Provides a web socket transport implementation that supports GraphQLSubscription s.

If your project uses GraphQL s, you must include this library. This library only needs to be linked to your targets that configure the WebSocketTransport and pass it to the ApolloClient.

For more information, see Enabling GraphQL subscription support.

ApolloTestSupport

Includes the APIs for creating test mocks for your generated models

Link this library to unit test targets that need to create mocks of generated models.

ApolloCodegenLib

Includes the code generation engine for generating GraphQL models.

For most projects, we strongly recommend using the Codegen CLI instead of using ApolloCodegenLib directly.

Use this library if you want to run the code generation engine from your own Swift executable targets.

Link this library to development tools that want to use the Apollo code generation engine. This library only supports macOS.

ApolloCodegenLib shouldn't be linked to your application targets.

Previous
Get Started
Next
v1.0
Edit on GitHubEditForumsDiscord