Configure BaseUrl for imported OpenAPI feature

I am using Swagger/OpenAPI to autogenerate the api interface from a Django backend for an Aurelia frontend client.

This works really great, but I cant figure out how to configure the Base Url.

I can manually set it in the autogenerated files, but this gets overwritten whenever I regenerate the code.

In my main.ts I add the api as a feature and I thought i could do something like this:

  aurelia.use
    .standardConfiguration()
    .feature('api', {basePath: '/path/to/api/'})
    .feature('resources');

but that is not working. Does anyone have a tip for me?

1 Like

It really depends on what the generated files look like. The feature e.g can point to an index.ts which contains a configure function. So when the feature gets loaded this gets called first. In there you can manipulate or set things as you want. So if you can colocate the index.ts next to your generated files this should work.

1 Like

!Edited: no, this ( below) did not work actually. My manual edit of the basepath directly in the autogenerated code was still hanging around in some cached code. I will continue to hack around for a solution and post it here.


thanks @zewa666 , “configure function” was the key! I was trying to load some configuration as an object. I looked at how some other plugins were being registered.

Here is the correct way to configure the basePath:

  aurelia.use
    .standardConfiguration()
    .feature('api', baseConfig => {
      baseConfig.configure({basePath: '/path/to/api/'});
    })
    .feature('resources');

For anyone that is interested in using openapi, here’s how I have things set up.

the openapi cli is installed using npm or yarn:

npm install @openapitools/openapi-generator-cli -g

In Django I am using the Django Rest Framwork together with drf_yasg ( Yet another Swagger generator ).

The command to autogenerate the API interfaces for Aurelia:

openapi-generator generate -g typescript-aurelia -o ./my/aureali-app/src/api/ -i http://127.0.0.1:8000/path/to/api/swagger/?format=openapi --skip-validate-spec

The advantage is that you get all the typescript autosuggest options while writing code that connects to your server api. If you change your server side API, you can regenerate the typescript files. You get some minimal consistency checking when you build your aurelia app. If you try to access some fields that no longer exists you’ll get warnings and errors when you build your app.

By the way, a big “Thanks you!” to whoever wrote the aurelia exporters for openapi. I was not expecting this to all work so easily.

2 Likes

Just for future reference for anyone intereseted in using the openapi cli to autogenerate the api client for an Aurelia project.

My problem was the following:

The generated Api.ts file has a BASE_PATH variable that defines where base url of the API. If you are generating your files locally the url will be an absolute path to your local server and will fail when you deploy your code.

Its easy to change the BASE_PATH valud in the the Api.ts file, but this will get overwritten everytime you make a change to the api and regenerate your files.

Solution:

There is a .openapi-generator-ignore file that works like a .gitignorefile. Any files reference by name is this text file will not be overwritten by subsequent regeneration of the openapi filed.

Its pretty safe to add the Api.ts file, as it is just defines the generic base class that other API Classes inherit from, and does not change when your API is updated.

The client code can be imported into the project in the main.ts file as follows:

  aurelia.use
    .standardConfiguration()
    .feature('api')
    .feature('resources');
2 Likes

the aurelia client is written totally weird there imho. the baseUrl is more hardcoded than in typescript-fetch. so for now I’ll probably use typescript fetch and then alike:
main.ts

import * as Api from 'api';
//...

  const apiConfig = new Api.Configuration({
      basePath: 'http://localhost:5000/api/', 
  });
  aurelia.container.registerHandler(Api.SomeApi, () => new Api.SomeApi(apiConfig));

need to do that for all endpoints though, so might need tweaking. or ‘just’ fixing up on of the generators, so it’s better generated code in the first place

Bit late to the party but here is a solution in lieu of fixing the real problem of the basepath being hard coded as a non exported constant in a module.

Each api instance must be registered with the DI container using a helper function that sets the base path.

in main.ts

export function configure(aurelia: Aurelia): void {
   ...

     // get the basePath you want from some config like environment.ts
    const apiConfig = {
      basePath: appConfig.bookingsApiConfiguration.baseUrl // eg: https://localhost:45321/api
    }

     // register each api class using a helper function 'createApi' - see below
    aurelia.container.registerHandler(AccountApi, (c: Container) => createApi(c, AccountApi, apiConfig));
    aurelia.container.registerHandler(CandidateProfileApi, (c: Container) => createApi(c, CandidateProfileApi, apiConfig));
    aurelia.container.registerHandler(CandidatePhotoApi, (c: Container) => createApi(c, CandidatePhotoApi, apiConfig));

    ...
}

/** 
 * Creates a new instance of an Api and configures it 
 * @param container the aurealia container that will be used. Normally the root.
 * @param apiConstructor constructor function for an api class. Use the Type, eg) myAccountApi
 * @param config api configuration settings
*/
function createApi(container: Container, apiConstructor: new (httpClient: HttpClient, authStorage: AuthStorage) => Api, config: { basePath: string }) {

  const httpClient = container.get(HttpClient);
  const authStorage = container.get(AuthStorage);

  const api = new apiConstructor(httpClient, authStorage);
  api.basePath = config.basePath;

  return api;
}

Ideally the api generator code should be changed to allow a one line setup of the basepath. Perhaps I’ll get to that at a later time but openapi-generator requires building & testing the entire java project to tinker with a little script generation file. I gave up last time - so maybe later, when moving stuff it AU2 :slight_smile: