ApodiniMigrator
is a Swift package that performs several automated tasks, to migrate client applications after a Web Service publishes a new version that contains breaking changes. The tasks include automated generation of an intermediary client library that contains all required components to establish a client-server communication. Furthermore, ApodiniMigrator
is able to automatically generate a machine-readable migration guide in either json
or yaml
format, that describes the changes between two subsequent Web API versions, and includes auxiliary migrating actions. By means of the migration guide, ApodiniMigrator
can automatically migrate the intermediary client library, ensuring therefore the compatibility with the new Web API version. It is part of Apodini, a composable framework to build Web Services in using Swift.
This library requires at least Swift 5.5 and macOS 12. Furthermore, it makes use of an automatically generated Document
, that describes the interface of an Apodini Web Service. See Documentation in Apodini project, on how to integrate and configure ApodiniMigrator
in your Web Service to generate the Document
or a migration guide between two versions.
ApodiniMigrator
offers a Command-line interface program to execute its functionalities. After cloning the project, one can run the following commands on the root of the project to install migrator
CLI as well as the Protocol Buffer compiler plugin.
$ swift build --configuration release
$ cp -f .build/release/migrator /usr/local/bin/migrator
$ cp -f .build/release/protoc-gen-grpc-migrator /usr/local/bin/protoc-gen-grpc-migrator
To use the gRPC Apodini Migrator you will also need to install the Protocol Buffer compiler and the respective Swift plugins.
$ brew install protobuf
$ brew install swift-protobuf grpc-swift
After installing migrator
CLI, migrator --help
command gives an overview of its functionalities:
$ migrator --help
OVERVIEW: Automatically generate migration guides and migrate client libraries.
USAGE: migrator <subcommand>
OPTIONS:
-h, --help Show help information.
SUBCOMMANDS:
compare Compare API documents and automatically generate a migration guide between two versions.
migrate Migrate a client library using the base API document and a migration guide.
generate Generate a client library from an API document.
See 'migrator help <subcommand>' for detailed help.
compare
subcommand automatically generates a machine-readable migration guide in either json
or yaml
format after comparing documents of two different versions. Below its required arguments:
$ migrator compare --help
OVERVIEW: Compare API documents and automatically generate a migration guide between two versions.
USAGE: migrator compare --old-document-path <old-document-path> --new-document-path <new-document-path> --migration-guide-path <migration-guide-path> [--format <format>]
OPTIONS:
-o, --old-document-path <old-document-path>
Path to API document of the old version, e.g. /path/to/api_v1.0.0.json
-n, --new-document-path <new-document-path>
Path to API document of the new version, e.g. /path/to/api_v1.2.0.yaml
-m, --migration-guide-path <migration-guide-path>
Path to a directory where the migration guide should be persisted, e.g. /path/to/directory
-f, --format <format> Output format of the migration guide, either JSON or YAML. JSON by default (default: json)
-h, --help Show help information.
generate
subcommand can automatically generate an intermediary client library in the Swift programming language for supported WebAPI types.
The library includes all the models and API calling methods of an API Web Service and can be added as a dependency in an existing iOS or macOS using Swift Package Manager.
OVERVIEW: Generate a client library from an API document.
USAGE: migrator generate <subcommand>
OPTIONS:
-h, --help Show help information.
SUBCOMMANDS:
rest Generate a REST client library from an API document.
grpc Generate a gRPC client library from an API document.
See 'migrator help generate <subcommand>' for detailed help.
Subcommand for generating a RESTful client library:
$ migrator generate --help
OVERVIEW: Generate a REST client library from an API document.
USAGE: migrator generate rest --package-name <package-name> --target-directory <target-directory> --document-path <document-path>
OPTIONS:
-n, --package-name <package-name>
Name of the package
-t, --target-directory <target-directory>
Output path of the package (without package name)
-d, --document-path <document-path>
Path where the base api_vX.Y.Z file is located, e.g. /path/to/api_v1.0.0.json
-h, --help Show help information.
Subcommand for generating a gRPC client library:
OVERVIEW: Generate a gRPC client library from an API document.
USAGE: migrator generate grpc --package-name <package-name> --target-directory <target-directory> --document-path <document-path> --proto-path <proto-path> [--protoc-gen-dump-request-path <protoc-gen-dump-request-path>] [--protoc-grpc-plugin-path <protoc-grpc-plugin-path>]
OPTIONS:
-n, --package-name <package-name>
Name of the package
-t, --target-directory <target-directory>
Output path of the package (without package name)
-d, --document-path <document-path>
Path where the base api_vX.Y.Z file is located, e.g. /path/to/api_v1.0.0.json
-p, --proto-path <proto-path>
Path where the grpc proto file is located, e.g. /path/to/MyWebService.proto
--protoc-gen-dump-request-path <protoc-gen-dump-request-path>
Specify the path to which you want to dump the protoc plugin request binary. For Debugging purposes!
--protoc-grpc-plugin-path <protoc-grpc-plugin-path>
Manually specify the path to the `protoc-gen-grpc-migrator` protoco plugin.
-h, --help Show help information.
migrate
subcommand performs the automated migration of the intermediary client library generated in the previous step.
It makes use of the machine-readable migration guide and the Document
that initially generated the library:
OVERVIEW: Migrate a client library using the base API document and a migration guide.
USAGE: migrator migrate <subcommand>
OPTIONS:
-h, --help Show help information.
SUBCOMMANDS:
rest Migrate a gRPC client library from an API document and a migration guide.
grpc Migrate a gRPC client library from proto files, an API document and a migration guide.
See 'migrator help migrate <subcommand>' for detailed help.
Subcommand for migrating a RESTful client library:
$ migrator migrate --help
OVERVIEW: Migrate a gRPC client library from an API document and a migration guide.
USAGE: migrator migrate rest --package-name <package-name> --target-directory <target-directory> --document-path <document-path> --migration-guide-path <migration-guide-path>
OPTIONS:
-n, --package-name <package-name>
Name of the package
-t, --target-directory <target-directory>
Output path of the package (without package name)
-d, --document-path <document-path>
Path where the base api_vX.Y.Z file is located, e.g. /path/to/api_v1.0.0.json
-m, --migration-guide-path <migration-guide-path>
Path where the migration guide is located, e.g. /path/to/migration_guide.json
-h, --help Show help information.
Subcommand for generating a gRPC client library:
OVERVIEW: Migrate a gRPC client library from proto files, an API document and a migration guide.
USAGE: migrator migrate grpc --package-name <package-name> --target-directory <target-directory> --document-path <document-path> --migration-guide-path <migration-guide-path> --proto-path <proto-path> [--protoc-gen-dump-request-path <protoc-gen-dump-request-path>] [--protoc-grpc-plugin-path <protoc-grpc-plugin-path>]
OPTIONS:
-n, --package-name <package-name>
Name of the package
-t, --target-directory <target-directory>
Output path of the package (without package name)
-d, --document-path <document-path>
Path where the base api_vX.Y.Z file is located, e.g. /path/to/api_v1.0.0.json
-m, --migration-guide-path <migration-guide-path>
Path where the migration guide is located, e.g. /path/to/migration_guide.json
-p, --proto-path <proto-path>
Path where the grpc proto file is located, e.g. /path/to/MyWebService.proto
--protoc-gen-dump-request-path <protoc-gen-dump-request-path>
Specify the path to which you want to dump the protoc plugin request binary. For Debugging purposes!
--protoc-grpc-plugin-path <protoc-grpc-plugin-path>
Manually specify the path to the `protoc-gen-grpc-migrator` protoco plugin.
-h, --help Show help information.
ApodiniMigratorExample includes two different versions of an Apodini Web Service using ApodiniMigrator
configuration. The corresponding documents of those versions can be found in the ExampleDocuments of this repository. In order to test out the functionalities of migrator
CLI, a preconfigured Ruby script in the root of this repository can be used (see migrator)
In order to generate the intermediary client library for the initial version run the script with generate
argument:
$ ./migrator generate
2022-02-09T00:24:50+0100 info org.apodini.migrator.rest : Starting generation of package QONECTIQ
2022-02-09T00:24:50+0100 info org.apodini.migrator.rest : Starting library generation at: ~
2022-02-09T00:24:50+0100 info org.apodini.migrator.rest : Creating directory Sources at: ~/QONECTIQ
2022-02-09T00:24:50+0100 info org.apodini.migrator.rest : Creating directory QONECTIQ at: ~/QONECTIQ/Sources
2022-02-09T00:24:50+0100 info org.apodini.migrator.rest : Creating directory Endpoints at: ~/QONECTIQ/Sources/QONECTIQ
2022-02-09T00:24:50+0100 info org.apodini.migrator.rest : Handling library composite EndpointsMigrator at: ~/QONECTIQ/Sources/QONECTIQ/Endpoints
2022-02-09T00:24:50+0100 info org.apodini.migrator.rest : Rendering file Event+Endpoint.swift at: ~/QONECTIQ/Sources/QONECTIQ/Endpoints
2022-02-09T00:24:50+0100 info org.apodini.migrator.rest : Rendering file HomeFeed+Endpoint.swift at: ~/QONECTIQ/Sources/QONECTIQ/Endpoints
2022-02-08T23:08:31+0100 info org.apodini.migrator.rest : ...
2022-02-09T00:24:50+0100 info org.apodini.migrator.rest : Package QONECTIQ was generated successfully. You can open the package via QONECTIQ/Package.swift
Each endpoint of the library can be accessed via the caseless enumeration API
as follows:
API.getEventWithID(id: UUID())
.sink { completion in
if case let .failure(error) = completion {
print("Failed to get the event with error: \(error)")
}
} receiveValue: { event in
print("Received event \(event.title)")
}
Migration guide can be generated via:
$ ./migrator compare
info org.apodini.migrator : Starting generation of the migration guide...
info org.apodini.migrator : Migration guide was generated successfully at /path/to/ApodiniMigrator/Resources/ExampleDocuments/migration_guide.json.
Once the migration guide has been generated, use migrate
argument to migrate the initial library:
$ ./migrator migrate
2022-02-08T23:08:31+0100 info org.apodini.migrator.rest : Starting migration of package QONECTIQ
2022-02-08T23:08:31+0100 info org.apodini.migrator.rest : Starting library generation at: ~
2022-02-08T23:08:31+0100 info org.apodini.migrator.rest : Creating directory Sources at: ~/QONECTIQ
2022-02-08T23:08:31+0100 info org.apodini.migrator.rest : Creating directory QONECTIQ at: ~/QONECTIQ/Sources
2022-02-08T23:08:31+0100 info org.apodini.migrator.rest : Creating directory Endpoints at: ~/QONECTIQ/Sources/QONECTIQ
2022-02-08T23:08:31+0100 info org.apodini.migrator.rest : Handling library composite EndpointsMigrator at: ~/QONECTIQ/Sources/QONECTIQ/Endpoints
2022-02-09T00:24:50+0100 info org.apodini.migrator.rest : Rendering file Event+Endpoint.swift at: ~/QONECTIQ/Sources/QONECTIQ/Endpoints
2022-02-09T00:24:50+0100 info org.apodini.migrator.rest : Rendering file HomeFeed+Endpoint.swift at: ~/QONECTIQ/Sources/QONECTIQ/Endpoints
2022-02-08T23:08:31+0100 info org.apodini.migrator.rest : ...
2022-02-08T23:08:31+0100 info org.apodini.migrator.rest : Package QONECTIQ was migrated successfully. You can open the package via QONECTIQ/Package.swift
Contributions to the projects are welcome. Please make sure to read the contribution guidelines first.
This project is licensed under the MIT License. See License for more information.