Page updated Feb 7, 2024

Set up Amplify GraphQL API

The Amplify API category provides an interface for retrieving and persisting your model data. The API category comes with default built-in support for AWS AppSync. The Amplify CLI allows you to define your API and provision a GraphQL service with CRUD operations and real-time functionality.

Goal

To setup and configure your application with Amplify API to save items in the backend.

Prerequisites

An application with Amplify libraries integrated and a minimum target of any of the following:

  • iOS 13.0, using Xcode 14.1 or later.
  • macOS 10.15, using Xcode 14.1 or later.
  • tvOS 13.0, using Xcode 14.3 or later.
  • watchOS 9.0, using Xcode 14.3 or later.
  • visionOS 1.0, using Xcode 15 beta 2 or later. (Preview support - see below for more details.)

For a full example, please follow the project setup walkthrough.

visionOS support is currently in preview and can be used by targeting the visionos-preview branch. As new Xcode 15 beta versions are released, the branch will be updated with any necessary fixes on a best effort basis.

For more information on how to use the visionos-preview branch, see Platform Support.

Configure API

To start provisioning API resources in the backend, go to your project directory and execute the command:

amplify add api
1amplify add api

Enter the following when prompted:

? Please select from one of the below mentioned services: `GraphQL` # The part below will show you some options you can change, if you wish to change any of them you can navigate with # your arrow keys and update any field, otherwise you can click on `Continue` to move on ? Here is the GraphQL API that we will create. Select a setting to edit or continue `Continue` ? Choose a schema template: `Single object with fields (e.g., “Todo” with ID, name, description)` ? Do you want to edit the schema now? `No`
1? Please select from one of the below mentioned services:
2 `GraphQL`
3# The part below will show you some options you can change, if you wish to change any of them you can navigate with
4# your arrow keys and update any field, otherwise you can click on `Continue` to move on
5? Here is the GraphQL API that we will create. Select a setting to edit or continue
6 `Continue`
7? Choose a schema template:
8 `Single object with fields (e.g., “Todo” with ID, name, description)`
9? Do you want to edit the schema now?
10 `No`

Troubleshooting: The AWS API plugins do not support conflict detection. If AppSync returns errors about missing _version and _lastChangedAt fields, or unhandled conflicts, disable conflict detection. Run amplify update api, and choose Disable conflict detection. If you started with the Getting Started guide, which introduces DataStore, this step is required.

The guided schema creation will output amplify/backend/api/{api_name}/schema.graphql containing the following:

type Todo @model { id: ID! name: String! description: String }
1type Todo @model {
2 id: ID!
3 name: String!
4 description: String
5}

To push your changes to the cloud, execute the command:

amplify push
1amplify push

Upon completion, amplifyconfiguration.json will be updated to reference provisioned backend resources. Note that this file should already be a part of your project if you followed the Project setup walkthrough.

Generate Todo Model class

To generate the Todo model, change directories to your project folder and execute the command:

amplify codegen models
1amplify codegen models

The generated files will be under the amplify/generated/models directory. It is strongly advised not to put any hand written code in amplify/generated directory as it gets re-generated each time codegen is run.

AmplifyModels.swift Todo.swift Todo+Schema.swift
1AmplifyModels.swift
2Todo.swift
3Todo+Schema.swift

Drag and place the entire models directory into Xcode to add them to your project.

Install Amplify Libraries

  1. To install Amplify Libraries in your application, open your project in Xcode and select File > Add Packages....

  2. Enter the Amplify Library for Swift GitHub repo URL (https://github.com/aws-amplify/amplify-swift) into the search bar and click Add Package.

Note: Up to Next Major Version should be selected from the Dependency Rule dropdown.

  1. Lastly, choose AWSAPIPlugin and Amplify and click Add Package.

Initialize Amplify API

To initialize the Amplify API category, you are required to use the Amplify.add() method for the plugin followed by calling Amplify.configure().

Create a custom AppDelegate with the following imports and application:didFinishLaunchingWithOptions method:

import Amplify import AWSAPIPlugin import UIKit class AppDelegate: NSObject, UIApplicationDelegate { func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { do { try Amplify.add(plugin: AWSAPIPlugin(modelRegistration: AmplifyModels())) try Amplify.configure() print("Amplify configured with API plugin") } catch { print("Failed to initialize Amplify with \(error)") } return true } }
1import Amplify
2import AWSAPIPlugin
3import UIKit
4
5class AppDelegate: NSObject, UIApplicationDelegate {
6 func application(
7 _ application: UIApplication,
8 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 ) -> Bool {
10
11 do {
12 try Amplify.add(plugin: AWSAPIPlugin(modelRegistration: AmplifyModels()))
13 try Amplify.configure()
14 print("Amplify configured with API plugin")
15 } catch {
16 print("Failed to initialize Amplify with \(error)")
17 }
18
19 return true
20 }
21}

Then in your App scene, use the UIApplicationDelegateAdaptor property wrapper to use your custom AppDelegate:

@main struct MyAmplifyApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var body: some Scene { WindowGroup { ContentView() } } }
1@main
2struct MyAmplifyApp: App {
3 @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
4
5 var body: some Scene {
6 WindowGroup {
7 ContentView()
8 }
9 }
10}

Add the following imports to the top of your AppDelegate.swift file:

import Amplify import AWSAPIPlugin
1import Amplify
2import AWSAPIPlugin

Add the following code to the AppDelegate's application:didFinishLaunchingWithOptions method:

func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { do { try Amplify.add(plugin: AWSAPIPlugin(modelRegistration: AmplifyModels())) try Amplify.configure() print("Amplify configured with API plugin") } catch { print("Failed to initialize Amplify with \(error)") } return true }
1func application(
2 _ application: UIApplication,
3 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
4) -> Bool {
5
6 do {
7 try Amplify.add(plugin: AWSAPIPlugin(modelRegistration: AmplifyModels()))
8 try Amplify.configure()
9 print("Amplify configured with API plugin")
10 } catch {
11 print("Failed to initialize Amplify with \(error)")
12 }
13
14 return true
15}

Upon building and running this application you should see the following in your console window:

Amplify configured with API plugin
1Amplify configured with API plugin

Create a Todo

func createTodo() async { let todo = Todo(name: "my first todo", description: "todo description") do { let result = try await Amplify.API.mutate(request: .create(todo)) switch result { case .success(let todo): print("Successfully created the todo: \(todo)") case .failure(let graphQLError): print("Failed to create graphql \(graphQLError)") } } catch let error as APIError { print("Failed to create a todo: ", error) } catch { print("Unexpected error: \(error)") } }
1func createTodo() async {
2 let todo = Todo(name: "my first todo", description: "todo description")
3 do {
4 let result = try await Amplify.API.mutate(request: .create(todo))
5 switch result {
6 case .success(let todo):
7 print("Successfully created the todo: \(todo)")
8 case .failure(let graphQLError):
9 print("Failed to create graphql \(graphQLError)")
10 }
11 } catch let error as APIError {
12 print("Failed to create a todo: ", error)
13 } catch {
14 print("Unexpected error: \(error)")
15 }
16}

Make sure you have the additional import at the top of your file

import Combine
1import Combine
func createTodo() -> AnyCancellable { let todo = Todo(name: "my first todo", description: "todo description") let sink = Amplify.Publisher.create { try await Amplify.API.mutate(request: .create(todo)) }.sink { completion in if case let .failure(error) = completion { print("Failed to create graphql \(error)") } } receiveValue: { result in switch result { case .success(let todo): print("Successfully created the todo: \(todo)") case .failure(let graphQLError): print("Could not decode result: \(graphQLError)") } } return sink }
1func createTodo() -> AnyCancellable {
2 let todo = Todo(name: "my first todo", description: "todo description")
3 let sink = Amplify.Publisher.create {
4 try await Amplify.API.mutate(request: .create(todo))
5 }.sink { completion in
6 if case let .failure(error) = completion {
7 print("Failed to create graphql \(error)")
8 }
9 }
10 receiveValue: { result in
11 switch result {
12 case .success(let todo):
13 print("Successfully created the todo: \(todo)")
14 case .failure(let graphQLError):
15 print("Could not decode result: \(graphQLError)")
16 }
17 }
18 return sink
19}

Upon successfully executing this code, you should see an instance of todo persisted in your dynamoDB table.

To navigate to your backend, run amplify console api and choose GraphQL. This will open the AppSync console to your GraphQL service. Select Data Sources and select the Resource link in your TodoTable to bring you to the DynamoDB Console. Select the items tab to see the Todo object that has been persisted in your database.

Next steps

Congratulations! You've created a Todo object in your database. Check out the following links to see other Amplify API use cases: