Openapi-generator: Feature: [TypeScript] "CollectParameters" to accept params as option-bag

Created on 21 Aug 2018  Â·  15Comments  Â·  Source: OpenAPITools/openapi-generator

Description

I would like the TypeScript code generator to support "CollectParameters" extension, which tells generated methods to accept all parameters as a single object / option-bag instead of multiple, positional arguments.

This extension is described here:
https://blog.apimatic.io/swagger-2-0-extension-for-code-generation-settings-abf602c3869d

openapi-generator version

3.2.1

OpenAPI declaration file content or url
paths:
  /favorites:
    get:
      operationId: GetFavorites
      x-operation-settings:
        CollectParameters: true
      parameters:
        - in: query
          name: account_id
          type: string
        - in: query
          name: user_id
          type: string
      responses:
        '200':
          description: '200'
          schema:
            $ref: '#/definitions/Favorites'

CollectParameters: true should generate client methods that accept an option-bag of params.

await client.getFavorites({account_id: '123', user_id: '456'});
Related issues/PRs

Rewrite of TypeScript generators

TypeScript Feature help wanted

Most helpful comment

@Kiran-Sivakumar For typescript, using a destructured options bag is pretty standard. I would be more inclined to use that over a builder pattern.

const foo = ({ bar1, bar2, bar3 }: { bar1: string, bar2?: number, bar3: string[] }) => { ... }

I found this issue because this is exactly what I am looking for. I have imported and generated FHIR objects, which can have a ton of options, which look like...

  public patientGet(
    active?: string,
    address?: string,
    addressCity?: string,
    addressCountry?: string,
    addressPostalcode?: string,
    addressState?: string,
    addressUse?: string,
    birthdate?: string,
    deathDate?: string,
    deceased?: string,
    email?: string,
    family?: string,
    gender?: string,
    generalPractitioner?: string,
    given?: string,
    identifier?: string,
    language?: string,
    link?: string,
    name?: string,
    organization?: string,
    phone?: string,
    phonetic?: string,
    telecom?: string,
    testfamily?: string,
    format?: string
  ) => { ... }

Oh look, I need format - lemme just specify 24 undefined values before the one I need. Needless to say, that is less than desirable.

Any update on if/when this may make it in? I'm currently following issue 802. Thanks!

All 15 comments

@TiFu maybe this can also be considered in the rewrite of the TS generators?

Will keep this in mind.

@TiFu the code-gen changes should be really minimal. Given a function signature like this:

fooOperation(fooId: FooId, otherParam: OtherParamType) {

The CollectParameters version looks almost identical:

fooOperation({fooId, otherParam}: {fooId: FooId, otherParam: OtherParamType}) {

When none of the params are required, then append a default value so that the option-bag can be omitted entirely:

fooOperation({fooId, otherParam}: {fooId?: FooId, otherParam?: OtherParamType} = {}) {

@cspotcode Another option would be to create interfaces for these parameter bags

e.g.

interface FooOperationParam {
      fooId: FooId,
      otherParam: OtherParamType
}

fooOperation(param: FooOperationParam) { }

// if all params are optional:
fooOperation(param: FooOperationParam = {})

What would you prefer?

No preference. I merely wanted to show that argument destructuring can be
used to avoid any changes to the body of each method. The signature will
be different, but the method body will still refer to each parameter via a
local identifier. No need for property access expressions, e.g.
params.foo

On Wed, Aug 22, 2018, 12:00 PM Tino Fuhrmann notifications@github.com
wrote:

@cspotcode https://github.com/cspotcode Another option would be to
create classes for these parameter bags

e.g.

interface FooOperationParam {
fooId: FooId,
otherParam: OtherParamType
}

fooOperation(param: FooOperationParam) { }

// if all params are optional:
fooOperation(param: FooOperationParam = {})

What would you prefer?

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/OpenAPITools/openapi-generator/issues/865#issuecomment-415085177,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAW-uNqQyFcioeOiSZVMTkDTXzlDRBA7ks5uTYAygaJpZM4WF-_Z
.

There were similar suggestions before but nothing has been implemented yet. The use case was that the method contains many optional parameters, which will make the method signature very long in languages such as Java.

Related: https://github.com/OpenAPITools/openapi-generator/issues/641

@TiFu If I want to take a stab at implementing this issue, which branch should I base my code on?

FYI. I've added group parameters support to PHP API client: https://github.com/OpenAPITools/openapi-generator/pull/1337

Hi all,

I've tried to add group parameters support to TS Fetch client with some fake parameters to illustrate the change in https://github.com/OpenAPITools/openapi-generator/pull/1394.

https://github.com/OpenAPITools/openapi-generator/pull/1394/files#diff-157014844e879c93896c6ee0805f91ddR1541 is a good starting point to review the change.

Please review and let me know if you've any feedback.

Disclaimer: I'm no expert in TypeScript

Thanks,
William

cc @TiFu (2017/07) @taxpon (2017/07) @sebastianhaas (2017/07) @kenisteward (2017/07) @Vrolijkx (2017/09) @macjohnny (2018/01) @nicokoenig (2018/09) @topce (2018/10)

Hi all, I have made a PR for Java okhttp-gson API client addressing the same issue of method signatures being too long and inflexible: https://github.com/OpenAPITools/openapi-generator/pull/1341

However, instead of "group parameters", my solution employs the builder pattern for API requests (https://github.com/OpenAPITools/openapi-generator/issues/1217)

Currently, the vendor extension is x-group-parameters. This name is not appropriate for my PR given my solution. However, having the same vendor extension is ideal. My proposals for a new more general name for this vendor extension are as follows:
x-flexible-parameters
x-unrestrictive-parameters

Anyone have any thoughts on this?

@Kiran-Sivakumar For typescript, using a destructured options bag is pretty standard. I would be more inclined to use that over a builder pattern.

const foo = ({ bar1, bar2, bar3 }: { bar1: string, bar2?: number, bar3: string[] }) => { ... }

I found this issue because this is exactly what I am looking for. I have imported and generated FHIR objects, which can have a ton of options, which look like...

  public patientGet(
    active?: string,
    address?: string,
    addressCity?: string,
    addressCountry?: string,
    addressPostalcode?: string,
    addressState?: string,
    addressUse?: string,
    birthdate?: string,
    deathDate?: string,
    deceased?: string,
    email?: string,
    family?: string,
    gender?: string,
    generalPractitioner?: string,
    given?: string,
    identifier?: string,
    language?: string,
    link?: string,
    name?: string,
    organization?: string,
    phone?: string,
    phonetic?: string,
    telecom?: string,
    testfamily?: string,
    format?: string
  ) => { ... }

Oh look, I need format - lemme just specify 24 undefined values before the one I need. Needless to say, that is less than desirable.

Any update on if/when this may make it in? I'm currently following issue 802. Thanks!

We have a similar issue, but for us it is the upgrade of the generated API. Some parametes are added in between, some are removed, most are strings so there is no type checking and we only set a few and mostly they are called with undefined.

An example is:

public sampleFkt(param1: string = "1", param2: string = "2", param3: string = "3", para4: string = "4", param5: string = "6", param7: string = "7", param7: string = "8", param9: string = "9", param10: string = "10");
// called with
public public sampleFkt(undefined, undefined, undefined, undefined, undefined, undefined, "Hello", "World", "!");
// which gets changed to
public sampleFkt(param1: string = "1", param2: string = "2", param3: string = "3", para4: string = "4", param5: string = "6", param7: string = "7", NEWPARAM: string = "NEWPARAM" param7: string = "8", param9: string = "9", param10: string = "10");

Always a pain to find this, and very error prone.

this is implemented for typescript-fetch, see #3349

this is implemented for typescript-angular, see https://github.com/OpenAPITools/openapi-generator/pull/4479

Was this page helpful?
0 / 5 - 0 ratings