From 25cbb8ba69dfcb304275f6e02fb8b9729fae4805 Mon Sep 17 00:00:00 2001 From: RJPearson94 Date: Thu, 10 Jun 2021 21:57:47 +0100 Subject: [PATCH] feat: update the `api.mustache` template and go generator to support JSON media type for the request body The Go Generator has been updated to add a vendor extension to set `x-is-json` to true when the consume media type is `application/json` and `x-is-form` when the consumes media type is `application/x-www-form-urlencoded` The `x-is-json` vendor extension is used to generate the code to handle calling the new PostJson function or the corresponding HTTP method function on the request handler. This is designed to only work with Post requests at the moment but could be extended in the future if needed. This PR aids in resolving https://github.com/twilio/twilio-oai-generator/issues/49 however once this PR is merged https://github.com/twilio/twilio-oai/issues/36 will need to be finished to fully resolve the issue This change relies on https://github.com/twilio/twilio-go/pull/83 and the tests cannot be updated until this PR is merged and released This change also fixes an issue with JSON struct tags for the Params structs being `html-escaped`. I have disabled the escaping by using `{{{}}}` as this was highlighted during linting the Go SDK repo --- .../com/twilio/oai/TwilioGoGenerator.java | 37 +++++++++++++++++-- src/main/resources/twilio-go/api.mustache | 23 +++++++++--- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/twilio/oai/TwilioGoGenerator.java b/src/main/java/com/twilio/oai/TwilioGoGenerator.java index 8dc93f5f0..841af4cc9 100644 --- a/src/main/java/com/twilio/oai/TwilioGoGenerator.java +++ b/src/main/java/com/twilio/oai/TwilioGoGenerator.java @@ -1,7 +1,13 @@ package com.twilio.oai; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; + import io.swagger.v3.oas.models.OpenAPI; import org.openapitools.codegen.CodegenParameter; +import org.openapitools.codegen.CodegenOperation; import org.openapitools.codegen.SupportingFile; public class TwilioGoGenerator extends AbstractTwilioGoGenerator { @@ -40,9 +46,33 @@ public void processOpenAPI(final OpenAPI openAPI) { .forEach(operation -> operation.addTagsItem(PathUtils.cleanPath(name)))); } + @SuppressWarnings("unchecked") + @Override + public Map postProcessOperationsWithModels(final Map objs, + final List allModels) { + final Map results = super.postProcessOperationsWithModels(objs, allModels); + + final Map ops = (Map) results.get("operations"); + final List opList = (List) ops.get("operation"); + + for (final CodegenOperation co : opList) { + Optional.ofNullable(co.consumes).orElse(Collections.emptyList()).stream().forEach(consumes -> { + final String mediaType = consumes.get("mediaType"); + if ("application/json".equals(mediaType)) { + co.vendorExtensions.put("x-is-json", true); + } + if ("application/x-www-form-urlencoded".equals(mediaType)) { + co.vendorExtensions.put("x-is-form", true); + } + }); + } + + return results; + } + /** - * Configures a friendly name for the generator. This will be used by the generator to select the library with the - * -g flag. + * Configures a friendly name for the generator. This will be used by the + * generator to select the library with the -g flag. * * @return the friendly name for the generator */ @@ -52,7 +82,8 @@ public String getName() { } /** - * Returns human-friendly help for the generator. Provide the consumer with help tips, parameters here + * Returns human-friendly help for the generator. Provide the consumer with help + * tips, parameters here * * @return A string value for the help message */ diff --git a/src/main/resources/twilio-go/api.mustache b/src/main/resources/twilio-go/api.mustache index 04326bad8..9f6ccd90e 100644 --- a/src/main/resources/twilio-go/api.mustache +++ b/src/main/resources/twilio-go/api.mustache @@ -19,7 +19,7 @@ import ( type {{{nickname}}}Params struct { {{#optionalParams}} // {{{description}}} - {{paramName}} *{{{dataType}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"{{#withXml}} xml:"{{baseName}}{{#isXmlAttribute}},attr{{/isXmlAttribute}}"{{/withXml}}{{#vendorExtensions.x-go-custom-tag}}{{/vendorExtensions.x-go-custom-tag}}` + {{paramName}} *{{{dataType}}} `json:"{{{baseName}}}{{^required}},omitempty{{/required}}"{{#withXml}} xml:"{{baseName}}{{#isXmlAttribute}},attr{{/isXmlAttribute}}"{{/withXml}}{{#vendorExtensions.x-go-custom-tag}}{{/vendorExtensions.x-go-custom-tag}}` {{/optionalParams}} } @@ -49,9 +49,21 @@ func (c *ApiService) {{{nickname}}}({{#allParams}}{{#required}}{{paramName}} {{{ path = strings.Replace(path, "{"+"{{paramName}}"+"}", {{^isString}}fmt.Sprint({{/isString}}{{paramName}}{{^isString}}){{/isString}}, -1) {{/pathParams}} +{{#vendorExtensions.x-is-json}} +{{#bodyParam.baseName}} + var data {{{bodyParam.baseName}}} + if params.{{{bodyParam.baseName}}} != nil { + data = *params.{{{bodyParam.baseName}}} + } else { + data = {{{bodyParam.baseName}}}{} + } +{{/bodyParam.baseName}} +{{^bodyParam.baseName}} + data := make(map[string]interface{}) +{{/bodyParam.baseName}} +{{/vendorExtensions.x-is-json}} +{{^vendorExtensions.x-is-json}} data := url.Values{} - headers := make(map[string]interface{}) - {{#hasOptionalParams}} {{#optionalParams}} {{^vendorExtensions.x-is-account-sid}} @@ -94,7 +106,8 @@ func (c *ApiService) {{{nickname}}}({{#allParams}}{{#required}}{{paramName}} {{{ {{/vendorExtensions.x-is-account-sid}} {{/optionalParams}} {{/hasOptionalParams}} - +{{/vendorExtensions.x-is-json}} + headers := make(map[string]interface{}) {{#hasHeaderParams}} {{#headerParams}} if params != nil && params.{{paramName}} != nil { @@ -103,7 +116,7 @@ func (c *ApiService) {{{nickname}}}({{#allParams}}{{#required}}{{paramName}} {{{ {{/headerParams}} {{/hasHeaderParams}} - resp, err := c.requestHandler.{{httpMethod}}(c.baseURL+path, data, headers) + resp, err := c.requestHandler.{{httpMethod}}{{#vendorExtensions.x-is-json}}Json{{/vendorExtensions.x-is-json}}(c.baseURL+path, data, headers) {{#returnType}} if err != nil { return nil, err