Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[kotlin] Fix optional header params in openhttp client #7341

Merged
merged 3 commits into from
Sep 17, 2020

Conversation

isycat
Copy link
Contributor

@isycat isycat commented Sep 3, 2020

This change adjusts the kotlin openhttp api template to ignore null headers when building the request rather than convert them to "null" string

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • If contributing template-only or documentation-only changes which will change sample output, build the project beforehand.
  • Run the shell script ./bin/generate-samples.shto update all Petstore samples related to your fix. This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master. These must match the expectations made by your contribution. You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*. For Windows users, please run the script in Git BASH.
  • File the PR against the correct branch: master
  • Copy the technical committee to review the pull request if your PR is targeting a particular programming language.

Isabella de Andrade 🐰 added 2 commits September 3, 2020 15:20
This commit adjusts the kotlin openhttp api template to:
1. Default optional parameters to null so that API consumers are no longer forced to specify a value
2. Ignore null headers when building the request rather than convert them to "null" string
@isycat isycat marked this pull request as ready for review September 3, 2020 14:59
@@ -40,7 +40,7 @@ import {{packageName}}.infrastructure.toMultiValue
{{#isDeprecated}}
@Deprecated(message = "This operation is deprecated.")
{{/isDeprecated}}
{{^doNotUseRxAndCoroutines}}{{#useCoroutines}}suspend {{/useCoroutines}}{{/doNotUseRxAndCoroutines}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{{dataType}}}{{^required}}?{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) : {{#returnType}}{{{returnType}}}{{#nullableReturnType}}?{{/nullableReturnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}} {
{{^doNotUseRxAndCoroutines}}{{#useCoroutines}}suspend {{/useCoroutines}}{{/doNotUseRxAndCoroutines}}fun {{operationId}}({{#allParams}}{{{paramName}}}: {{{dataType}}}{{^required}}? = null{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) : {{#returnType}}{{{returnType}}}{{#nullableReturnType}}?{{/nullableReturnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}} {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that this will be a breaking change if sortParamsByRequiredFlag is false. If you specify a default value before other parameters with no default value, you can only invoke the method with named parameters.

This will also potentially break Java interop as it would require @JvmOverloads on all methods, and this could have a non-trivial overhead on larger generated clients.

The only good way I see to address those concerns would be to put this functionality behind a new user option (something like defaultOptionalArgsToNull) and default it to true, which I think would work if we get this into the 5.0 release.

Then this change would become:

{{^required}}?{{#defaultOptionalArgsToNull}} = null{{/defaultOptionalArgsToNull}}{{/required}}

I don't know if defaultOptionalArgsToNull is the best name, though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use the sortParamsByRequiredFlag to false, because of some bugs caused by the reorder of the parameters in the past, so I agree with the new flag, to ensure the correct behaviour of sortParamsByRequiredFlag.

Copy link
Contributor Author

@isycat isycat Sep 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I have misunderstood something, there is no breakage within kotlin from adding = null. You can pass positioned params for a method that has defaulted params before others:

private fun catOld(optionalParam: String?, requiredParam: Int, optionalParam2: String?): String {
    return "$optionalParam$requiredParam$optionalParam2"
}

private fun cat(optionalParam: String? = null, requiredParam: Int, optionalParam2: String? = null): String {
    return "$optionalParam$requiredParam$optionalParam2"
}

@Test
fun testOptionalFirst() {
    // Without defaults, all 3 values must be specified
    assertEquals("123", catOld("1", 2, "3"))
    assertEquals("123", catOld("1", 2, optionalParam2 = "3"))
    assertEquals("123", catOld("1", requiredParam = 2, optionalParam2 = "3"))
    assertEquals("123", catOld(optionalParam = "1", requiredParam = 2, optionalParam2 = "3"))

    // With defaults, the same possible combinations are still valid
    assertEquals("123", cat("1", 2, "3"))
    assertEquals("123", cat("1", 2, optionalParam2 = "3"))
    assertEquals("123", cat("1", requiredParam = 2, optionalParam2 = "3"))
    assertEquals("123", cat(optionalParam = "1", requiredParam = 2, optionalParam2 = "3"))

    // plus:
    assertEquals("12null", cat("1", 2))
    assertEquals("12null", cat("1", requiredParam = 2))
    assertEquals("12null", cat(optionalParam = "1", requiredParam = 2))
    assertEquals("null23", cat(requiredParam = 2, optionalParam2 = "3"))
}

(Was this a recent kotlin change?)

The Java overloads concern sounds legitimate (and therefore also the ability to turn the behavior off)

I am not sure when I will be able to squeeze in the new config param change, so I am going to separate the null defaulting from this PR, so as to not block the null string fix.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(PR updated with null defaulting removed and generated petstore changes)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Was this a recent kotlin change?)

It's been around a while, but I recall being surprised by it when I started using Kotlin because it wasn't documented. The documentation was later updated August 2017 to clarify the corner case. I think most people who started learning Kotlin before this doc update probably don't know it's even a thing, most likely because we're all using named args for clarity :)

@jimschubert
Copy link
Member

cc kotlin technical committee @dr4ke616 @karismann @Zomzog @andrewemery @4brunu @yutaka0m

@isycat isycat changed the title Fix generation of optional parameters in openhttp kotlin-client api template Fix handling of optional header parameters in openhttp kotlin-client api template Sep 4, 2020
@jimschubert jimschubert added this to the 5.0.0 milestone Sep 17, 2020
@jimschubert
Copy link
Member

Looks good. Thanks for offering to address the default argument issue separately… it definitely makes the smaller reviews easier.

@jimschubert jimschubert changed the title Fix handling of optional header parameters in openhttp kotlin-client api template [kotlin] Fix optional header params in openhttp client Sep 17, 2020
@jimschubert jimschubert merged commit bb00d88 into OpenAPITools:master Sep 17, 2020
@isycat isycat deleted the 2012-kotlin-optional-params branch September 18, 2020 11:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants