openapi-typescript-codegen icon indicating copy to clipboard operation
openapi-typescript-codegen copied to clipboard

Option to export plain functions instead of classes with static methods

Open philer-jambit opened this issue 2 years ago • 2 comments

Currently the generated API client consists of *Service classes which have a bunch of static methods to call the individual end points. This serves as a sort of name spacing, which is arguably already an anti pattern in JS/TS.

Instead it would be much preferable if the exports were plain functions. Instead of:

export class FooService {
    public static getFoo(...args: Args) {
        return __request(...args)
    }
}

that would just be:

export const getFoo = (...args: Args) => __request(...args)

If you are worried about name duplication you can import from the relevant files directly, such as

import * as fooService from '.../apiclient/services/fooService'

That said, the operationId from openapi.json is already meant to be unique, so there really should never be a case where naming collisions are possible.

Advantages of this approach include:

  • less code / more idiomatic (both in the generated code and the code that uses it)
  • allows tree shaking of unused end points – This is a big one. Consider using only one or two end points from an API that has dozens or even hundreds of end points that all fall into the same service – you may argue about the design choices there but APIs are not always defined by those who use them.
  • easy to mock individual imports in testing e.g. with jest

philer-jambit avatar Aug 09 '22 13:08 philer-jambit

I ran into this issue today. It wasn't obvious to me from the documentation (or I didn't read it carefully enough) but if you use the --name property it will generate non-static service classes that you can instantiate individually. You can also access instances through the client wrapper class that is generated based on the --name parameter.

sethmiller avatar Sep 19 '22 22:09 sethmiller

Yes, but then you still have one class per service, which is not tree-shakable.

Would be really cool if this library had a custom service-template option. I implemented a basic version of this here: https://github.com/ferdikoomen/openapi-typescript-codegen/pull/1268

mb21 avatar Sep 21 '22 15:09 mb21