From ef06419f9d6de68fe67d1a2af769271dd5e5599a 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 | 35 +++++++++++++++++-- src/main/resources/twilio-go/api.mustache | 23 +++++++++--- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/twilio/oai/TwilioGoGenerator.java b/src/main/java/com/twilio/oai/TwilioGoGenerator.java index a469ce936..d460216bc 100644 --- a/src/main/java/com/twilio/oai/TwilioGoGenerator.java +++ b/src/main/java/com/twilio/oai/TwilioGoGenerator.java @@ -1,7 +1,11 @@ package com.twilio.oai; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.openapitools.codegen.CodegenOperation; import org.openapitools.codegen.SupportingFile; public class TwilioGoGenerator extends AbstractTwilioGoGenerator { @@ -13,9 +17,33 @@ public void processOpts() { supportingFiles.add(new SupportingFile("README.mustache", "README.md")); } + @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 */ @@ -25,7 +53,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 f31e9e76e..4ad8978de 100644 --- a/src/main/resources/twilio-go/api.mustache +++ b/src/main/resources/twilio-go/api.mustache @@ -36,7 +36,7 @@ func New{{classname}}ServiceWithClient(client twilio.BaseClient) *{{classname}}S 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}} } @@ -66,9 +66,21 @@ func (c *{{{classname}}}Service) {{{nickname}}}({{#allParams}}{{#required}}{{par {{/vendorExtensions.x-is-account-sid}} {{/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}} @@ -98,7 +110,8 @@ func (c *{{{classname}}}Service) {{{nickname}}}({{#allParams}}{{#required}}{{par {{/vendorExtensions.x-is-account-sid}} {{/optionalParams}} {{/hasOptionalParams}} - +{{/vendorExtensions.x-is-json}} + headers := make(map[string]interface{}) {{#hasHeaderParams}} {{#headerParams}} if params != nil && params.{{paramName}} != nil { @@ -107,7 +120,7 @@ func (c *{{{classname}}}Service) {{{nickname}}}({{#allParams}}{{#required}}{{par {{/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