Using swagger-codegen with ReactNative

Lupu Gabriel
2 min readApr 19, 2018

--

Since you got here, you already know that ReactNative’s fetch()does not go along very well with the swagger-codegen generated JavaScript objects.

For those of you who are not determined by the idea of creating a new template for swagger-codegen, and if by the time you are reading this there isn’t one out there already, this is what I 🧐 suggest:

Concept

We will extend the swagger-codegen’s javascript generated ApiClient with our custom ReactNative class, that will be passed as instance for swagger-codegen’s generated API objects. Sounds crazy, I know, but it’s actually very straight forward.

Let’s get to business

1. Generate the magic JS files using swagger-codegen

java -jar ./scripts/swagger-codegen-cli.jar generate -i http://<your_rest_api>/api-docs -l javascript -o ./app/generated

The command above is just an example. If you don’t know what it does, I strongly recommend to check out their overview.

2. Create a new file inside your RN project, that will contain our extended class:

Let’s assume you’ll name it CustomApiClient.js. Here’s a article about how you can create a file 😅

3. Import ApiClient, and other Api generated objects that you intend to use:

import {
ApiClient,
UsersApi,
PetsApi
} from '../generated/src';

3. Create the class that extends ApiClient:

class CustomApiClient extends ApiClient { }

4. Override the magic ApiClient.callApi() function! 🍾

callApi(path, httpMethod, pathParams,queryParams,collectionQueryParams, headerParams, formParams, bodyParam,authNames, contentTypes, accepts,returnType, callback) {
return fetch(`${this.basePath}${path}`,
{
method: httpMethod,
headers: ...,
});
}

This is the place where you start hacking. The function’s signature takes a very long list of params that you can use for that. Also, additional updates are required for POST/ PUT etc. You can check the original definition of callApi() to get a better sense of what this is supposed to do.

5. Extend each generated Api Controller and override it’s constructor, in order to inject our own ApiClient

Hate it’s not DRY, but haven’t found a better solution 😞

class CustomUsersApi extends UsersApi {
constructor() {
super(new CustomApiClient());
}
}
class CustomPetsApi extends PetsApi {
constructor() {
super(new CustomApiClient());
}
}

6. Export your fantastic work

export {
CustomUsersApi,
CustomPetsApi
}

7. Use it in your application 👏

import CustomUsersApi from "../CustomApiClient";...CustomUsersApi.getUsersUsingGET()

Hacker’s quick copy-paste snippet:

import {
ApiClient,
UsersApi,
PetsApi
} from '../generated/src';
class CustomApiClient extends ApiClient {
callApi(path, httpMethod, pathParams,queryParams,collectionQueryParams, headerParams, formParams, bodyParam,authNames, contentTypes, accepts,returnType, callback) {
return fetch(`${this.basePath}${path}`,
{
method: httpMethod
});
}
}
class CustomUsersApi extends UsersApi {
constructor() {
super(new CustomApiClient());
}
}
class CustomPetsApi extends PetsApi {
constructor() {
super(new CustomApiClient());
}
}
export {
CustomUsersApi,
CustomPetsApi
}

After writing this article, I am already considering writing a ReactNative template for swagger-codegen, for us — the lazy hackers.

UPDATE:

If you’re receiving a superagent dependency error, simply add it to your dependencies.

--

--