In this tutorial, you are going to create a new library using CreateAPI that talks to the Swagger Petstore API.
- Getting Started
- Generating a Package
- Using the Code
- Adding a Configuration File
- Updating the Code
- Next Steps
If you haven't already heard about CreateAPI, it's a tool that allows you to generate Swift code from an OpenAPI specification.
For a new project, the easiest way to get started with CreateAPI is to generate a Swift Package. Once you have your package in place, you can add it as a dependency to your projects and use the generated interfaces just like you would with hand written code.
If you haven't already, be sure to install the create-api
CLI.
First things first, you need to generate the package. To do so, there is one key ingredient: The schema. Download the Petstore schema from https://petstore3.swagger.io/api/v3/openapi.json and save it somewhere accessible on your computer.
Using terminal, run the create-api generate
command like the following example:
$ create-api generate "schema.json" --output "./PetstoreKit" --config-option "module=PetstoreKit"
You might want to substitute the above values with the real ones so lets just go over what they are doing:
"schema.json"
- The path to the schema file that you downloaded earlier.--output "./PetstoreKit"
- Indicates that we want to write the generated package into the PetstoreKit directory.--config-option "module=PetstoreKit"
- Defines the name of the module (and package product) as PetstoreKit.
You will see something like the following printed to the console:
Generating code for schema.json...
And you will find a new folder called PetstoreKit located within the output directory. Double click on the Package.swift file within the package to open it in Xcode and you will see something like the following:
Once the dependencies have resolved, build the project and everything will succeed. Congratulations, you've generated your first project using CreateAPI!
Now that you have the generated Paths and Entities, you probably want to actually put them to good use!
To do this, you aren't going to make any changes to your newly generated Package because you might want to regenerate it later. Instead, you are going to integrate the package into a different project.
Close PetstoreKit if its open in Xcode and in the Menu click File ▸ New ▸ Project... and create a project called Petstore.
To integrate PetstoreKit within your Petstore project, drag the PetstoreKit folder from finder and drop it beneath the Petstore project in the project navigator:
The last thing you need to do before you can use your generated package is to add it under the Frameworks, Libraries, and Embedded Content section for the Petstore target:
All set! Now, in the Petstore group, add a new file called PetstoreClient.swift. Within that file, add the following code:
import Foundation
import Get
import PetstoreKit
public class PetstoreClient {
let api: APIClient
public init() {
self.api = APIClient(
baseURL: URL(string: "https://petstore3.swagger.io/api/v3")
)
}
public func findPets(by status: Paths.Pet.FindByStatus.Status) async throws -> [Pet] {
let request = Paths.pet.findByStatus.get(status: status)
let response = try await api.send(request)
return response.value
}
}
Lets summarize the key parts of this code:
- You import Get to access the
APIClient
. - You import PetstoreKit to access your generated paths and entities.
- You initialize the
PetstoreClient
'sapi
with the appropriatebaseURL
. - You define the
findPets(by:)
method that accepts a generated enum for thestatus
argument and returns an array of generatedPet
types. - You create the request that uses the generated
Paths
definition.
And that's it! You can now go ahead and use this code to build your Petstore! For example:
import PetstoreKit
import SwiftUI
struct ContentView: View {
let client = PetstoreClient()
@State private var pets: [Pet]? = nil
var body: some View {
if let pets = pets {
List {
Section("Sold") {
ForEach(pets, id: \.id) { pet in
Text(pet.name)
}
}
}
} else {
Text("Loading...")
.task {
self.pets = try? await client.findPets(by: .sold)
}
}
}
}
Now that you have learned the basics, you will probably find that you want to customize the generated code in one way or another. If so, you'll be happy to know that there are plenty of options available!
The vast majority of configuration options are managed through a yaml (or json) file that you specify using the --config
option when running the generator.
Lets say that you want your entities to automatically conform to the Identifiable
protocol, or you want to use a different style for the generated Paths. Go ahead and paste the following into a new filed called create-api.yaml:
module: PetstoreKit
entities:
includeIdentifiableConformance: true
paths:
style: operations
namespace: APIOperation
Note: To understand what these options mean and to discover other options, be sure to read the Configuration Options documentation.
Now that you've created a configuration file, the next step is to regenerate your source files. To do that, keep on reading.
You'll need to regenerate your code whenever your schema is updated or you make modifications to your configuration file. To do so, run a command like the following:
$ create-api generate "schema.json" --config "create-api.yaml" --output "./PetstoreKit" --clean
This is similar to the original command that you ran, but there are some key differences:
- You no longer need the
--config-option
override because we've defined themodule
name in the configuration file itself. - You tell the generator where to find the configuration file by using
--config "create-api.yaml"
. - You add the
--clean
option to ensure that the contents of the ./PetstoreKit directory are reset each time you run the generator. This helps to clean up unused files that might no longer be relevant.
In the output, you'll get a similar message to last time and if you go back to the Petstore project and try to build, you'll likely find that the project no longer compiles. Don't worry though, this is expected because your configuration now generates a slightly different output!
Take a look though the generated source files in PetstoreKit to see what has changed and have a go at updating your implementation of PetstoreClient
.
Congratulations for making it though this tutorial. Using CreateAPI to generate your API code can be a very powerful productivity booster. Because there are so many different types of APIs and different ways of working, it can take a bit of time to find flows that work best for you, but be sure to checkout the additional resources below to learn more about how to make the most of CreateAPI.
If you have any questions or feedback, you are always welcome to Submit an Issue.