Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/rekabhq/fantom

OpenAPI generator for Dart & Flutter
https://github.com/rekabhq/fantom

Last synced: 17 days ago
JSON representation

OpenAPI generator for Dart & Flutter

Awesome Lists containing this project

README

        

# Fantom


Bloc

Fantom is a cli tool for generating API layer in dart language based on OpenAPI Spec.

With fantom you can simply take an openapi file and generate all the code
you need for your api. we do not impose

### Get Started Quickly
1. Install `fantom`
```shell
$ dart pub global activate fantom
```
2. Generate API client
```shell
$ fantom generate openapi.yaml --dir=lib/src/network
```
**Result:** it will generate models in `lib/src/network/model` directory and APIs in `lib/src/network/api` directory

**NOTE:** you're openapi file can be in json or yaml format.
### More Advanced Options

- Separate models and APIs directories
```shell
$ fantom generate openapi.yaml --model-dir=lib/src/model --api-dir=lib/src/network
```
- Generate API layer as a standalone dart package
```shell
$ fantom generate openapi.yaml --package=packages/network
```

**Note:** it will generates a package called `network` inside `packages/network` from where `fantom generate` command runs.

### Use a config file instead of cli

With fantom you can define all youre configuration once inside a `fantom.yaml`
file or your project's `pubspec.yaml` file once and then every time you want to generate you're network client code you simply just run below commands

- Define configs inside project's `pubspec.yaml` or create a `fantom.yaml`
and run command
```shell
$ fantom generate
```

**NOTE:** you can use a any yaml (or json) file to define you're fantom config in then
run generate command with path to file

```shell
$ fantom generate my-config.yaml
```

#### Here is an example of fantom config file

- Simple fantom configuration
```yaml
fantom:
openapi: path/to/openapi/file
api-dir: packages/network/lib
model-dir: packages/network/lib/models
package-name: network
```
- Fantom config for standalone network client package
```yaml
fantom:
openapi: path/to/openapi/file
package: path/to/export/package/
package-name: my_network_client
recreate-package: false # by default is true
```
by default `recreate-package` is set to true. which deletes the old generated network client package completely each time you run `generate` command.
if you set it to `false` only the generated files inside the `lib` directory of the
generated package will be removed and new one will replace them

**NOTE:** fantom uses the file header in generated files to recognize they are generated by fantom. same recognision method is used when deleting generated files,
so try not to edit the file header by hand.

**Side Note:** fantom almost everywhere uses the same method to read `json` or `yaml` files
the file name and extension is irrelevent to fantom just the file content should be in valid format whether it is `json` or `yaml`. you can even write your fantom config in json format if you need to

### Read openapi file from URL

With fantom it is possible to path a url as the source of `openapi` file.

NOTE: you must also provide a path to store the downloaded file

here is how your fantom config will look like

```yaml
fantom:
openapi: https://myopenapi.com/source/of/openapi
download-path: where/to/save/openapi.json
api-dir: packages/network/lib
model-dir: packages/network/lib/models
package-name: network
```

### Exclude Paths and Components

you can exclude some paths and components from being generated by fantom cli. what happens
is fantom will read the openapi files and then remove the paths and components you excluded
so they won't be generated.

you can add the components and path you want to your fantom config to be excluded like below example

```yaml
fantom:
openapi: openapi_files/petstore.openapi.json
package: path/to/package/
package-name: my_api_package
excluded-paths:
- /pet -- [get, post] # only exclude get & post operation
- /pet/findByStatus # when no operation specified everything gets excluded
excluded-components:
- components/schemas/Shalgham
```

## Use the Generated code

#### Create an instance of the api class

```dart
import 'package:network/api.dart';

void createApiInstance(){
final dio = provideDio();
final api = FantomApi(dio);
}
```

Fantom uses `Dio` and needs an instance of `Dio` to operate. Note that we do not
impose any custom or extra configurations to the `Dio` instance provided. so you can be sure you're in control of how you configure you're `Dio` instance

#### Understand Api method options

A Fantom generated api method will have extra parameters to give you more ability
to customize the request you want to send

Here is an example of an api method generated

```dart
Future> getMessages({
...
// define custom content type for request
String? contentType,
// define custom content type for response
String? responseContentType,
// useCompute will make deserialization to run on a different Isolate
bool useCompute = false,
// add new or override headers
Map? extraHeaders,
// path a CancelToken so you will be able to cancel request
CancelToken? cancelToken,
}) async {
```

#### Understand return type Result
Generated api methods will have a return type of `Future>`
if the return type specified in openapi file is `MODEL`.

a `Result` object allows you to check whether the request was successful or not
you can do that simply by

```dart
final result = await fantomApi.userApi.getUserProfile();

if (result.isSuccessful) {
// show profile
} else {
// show error
}
```

#### Set Exception Mapper

Fantom provide exception mapping. this feature is very usefull to map network exceptions to something that can be easily used and understood by your logic or ui layer

```dart
FantomExceptionMapping.setMapper((final Exception e, stacktrace) {
_log(e);
_log(stacktrace);

if (e is SocketException) {
return MyCustomError(S.current.noInternet, exception: e);
}
if (e is FormatException) {
return MyCustomError(S.current.somethingWentWrongTryAgain, exception: e);
}
if (e is DioError) {
// return something else
}
});
```

#### Custom request body

Fantom provides each method that requires a body to be completely customzied. there are times that you need to completely customize the request body. Fantom provides this option. here is an example

```dart

final customDioRequestBody = SetPaymentRequestBody.custom({
"method": 'credit_card',
"price": {"amount": price, "currency": "USD"},
});

final result = await fantomApi.paymentApi.setPayment(
rideCode: task.ride.code,
body: body,
);
```

Another example

```dart
final pictureUploadingResult = await fantomApi.userApi.uploadAvatar(
body: UploadAvatarRequestBody.custom(
FormData.fromMap(
{'avatar': MultipartFile.fromFileSync(avatarFilePath)},
),
),
extraHeaders: {
"Authorization": "Bearer ${_currentAccessToken}",
},
);

```