Search code examples
reactjstypescriptaxiosopenapiopenapi-generator

How to use generated OpenAPI client inside React?


I have generated my API client with openapi-generator-cli generate -i https://linktomybackendswagger/swagger.json -g typescript-axios -o src/components/api --additional-properties=supportsES6=true

Now I have all the files inside my project but I have no clue how to implement this. How do I instantiate the API? Where do I configure the access token to be used? How do I know each method name for an endpoint?

After 2 hours of googling I can't seem to find a documentation for what seems like the most basic setup questions. Maybe I'm just looking in the wrong places. Can someone point me in the right direction?


Solution

  • Ok, so I figured out a way that I think is clean that I will document here for others that are going down the same path, which is:

    • Using an API that is using Authorization: Bearer <Token here>
    • Created the client with openapi-generator-cli using -g typescript-axios
    • Using OAS3

    Let's say you have an endpoint called UserPolicies. After generating the code via CLI each endpoint will have its own class inside the generated file api.ts with the name extended like so UserPoliciesApi.

    For using that endpoint the following setup is required.

    Example: Inside UserPolicyList.tsx:

    import { UserPoliciesApi } from './components/api/api';
    import { Configuration } from './components/api/configuration';
    
    const openapiConfig = new Configuration();
      openapiConfig.baseOptions = {
        headers: { Authorization: 'Bearer ' + cookies.access_token },
      };
    const openapi = new UserPoliciesApi(openapiConfig);
    

    Let's assume you want to make a GET call for api/Policies you can do so with:

    openapi.userPoliciesGetPolicies.then((response) => {
        console.log(response);
      })
      .catch((error) => {
        console.log(error);
    });
    

    Now, what I found inconvenient with this design is the boilerplate code necessary for making one simple api call. I wanted to be able to simply do one import and already have the access_token setup.

    So I created a wrapper class like this MyApi.tsx:

    import { Cookies } from 'react-cookie';
    import { Configuration } from './components/api/configuration';
    
    class MyApi {
      private cookies: Cookies;
    
      constructor() {
        this.cookies = new Cookies();
      }
    
      private accessToken = () => {
        return this.cookies.get('access_token');
      };
    
      private configuration = () => {
        const openapiConfig = new Configuration();
        openapiConfig.baseOptions = {
          headers: { Authorization: 'Bearer ' + this.accessToken() },
        };
        return openapiConfig;
      };
    
      public userPoliciesApi = () => {
        const api = new UserPoliciesApi(this.configuration());
        return api;
      };
    }
    
    export default MyApi.tsx;
    

    Now I you can easily replace the boilerplate and call with this:

    Inside UserPolicyList.tsx:

    import { MyApi } from './components/myapi/MyApi.tsx';
    
    const api = new MyApi();
    const userPoliciesApi = api.userPoliciesApi();
    
    userPoliciesApi.userPoliciesGetPolicies.then((response) => {
        console.log(response);
      })
      .catch((error) => {
        console.log(error);
    });