Skip to content

Commit

Permalink
update Go generator based on improved SDK from Decentro
Browse files Browse the repository at this point in the history
  • Loading branch information
dphuang2 committed Sep 25, 2023
1 parent ed0fcbd commit 47828bc
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 210 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public class CodegenParameter implements IJsonSchemaValidationProperties {
public String paramNameCamelCase() {
return StringUtils.camelize(paramName, CamelizeOption.LOWERCASE_FIRST_LETTER);
}

public String paramNameCamelCaseUpper() {
return StringUtils.camelize(paramName, CamelizeOption.UPPERCASE_FIRST_CHAR);
}
public String paramNameSnakeCase() {
return StringUtils.underscore(paramName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
public class CodegenSecurity {
public String name;
public String nameInCamelCase;
public String nameInPascalCase;
public String type;
public String scheme;
public Boolean isFirst;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5569,6 +5569,7 @@ private CodegenSecurity defaultCodegenSecurity(String key, SecurityScheme securi
final CodegenSecurity cs = CodegenModelFactory.newInstance(CodegenModelType.SECURITY);
cs.name = key;
cs.nameInCamelCase = camelize(key);
cs.nameInPascalCase = camelize(key, CamelizeOption.LOWERCASE_FIRST_LETTER);
cs.type = securityScheme.getType().toString();
cs.isCode = cs.isPassword = cs.isApplication = cs.isImplicit = false;
cs.isHttpSignature = false;
Expand Down
194 changes: 8 additions & 186 deletions generator/konfig-generator-api/src/main/resources/go/README.mustache
Original file line number Diff line number Diff line change
@@ -1,87 +1,28 @@
# Go API client for {{packageName}}
# {{packageName}} - {{infoName}}'s Go SDK

{{#appDescriptionWithNewLines}}
{{{.}}}
{{/appDescriptionWithNewLines}}

## Overview
This API client was generated by the [Konfig](https://konfigthis.com).

- API version: {{appVersion}}
- Package version: {{packageVersion}}
{{^hideGenerationTimestamp}}
- Build date: {{generatedDate}}
{{/hideGenerationTimestamp}}
{{#infoUrl}}
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
{{/infoUrl}}

## Installation

Add package to your project:
Add to your project:

```shell
go get {{gitHost}}/{{gitUserId}}/{{gitRepoId}}{{#isGoSubmodule}}/{{packageName}}{{/isGoSubmodule}}
```

Add the following in import:

```golang
import {{packageName}} "{{gitHost}}/{{gitUserId}}/{{gitRepoId}}{{#isGoSubmodule}}/{{packageName}}{{/isGoSubmodule}}"
```

To use a proxy, set the environment variable `HTTP_PROXY`:

```golang
os.Setenv("HTTP_PROXY", "http://proxy_name:proxy_port")
```

## Configuration of Server URL

Default configuration comes with `Servers` field that contains server objects as defined in the OpenAPI specification.

### Select Server Configuration

For using other server than the one defined on index 0 set context value `sw.ContextServerIndex` of type `int`.

```golang
import {{packageName}} "{{gitHost}}/{{gitUserId}}/{{gitRepoId}}{{#isGoSubmodule}}/{{packageName}}{{/isGoSubmodule}}"
configuration := {{packageName}}.NewConfiguration()
configuration.Context = context.WithValue(configuration.Context, {{packageName}}.ContextServerIndex, 1)
```

### Templated Server URL

Templated server URL is formatted using default variables from configuration or from context value `sw.ContextServerVariables` of type `map[string]string`.
Import in code:

```golang
import {{packageName}} "{{gitHost}}/{{gitUserId}}/{{gitRepoId}}{{#isGoSubmodule}}/{{packageName}}{{/isGoSubmodule}}"
configuration := {{packageName}}.NewConfiguration()
configuration.Context = context.WithValue(configuration.Context, {{packageName}}.ContextServerVariables, map[string]string{
"basePath": "v2",
})
```

Note, enum values are always validated and all unused variables are silently ignored.

### URLs Configuration per Operation

Each operation can use different server URL defined using `OperationServers` map in the `Configuration`.
An operation is uniquely identified by `"{classname}Service.{nickname}"` string.
Similar rules for overriding default operation server index and variables applies by using `sw.ContextOperationServerIndices` and `sw.ContextOperationServerVariables` context maps.

```golang
import {{packageName}} "{{gitHost}}/{{gitUserId}}/{{gitRepoId}}{{#isGoSubmodule}}/{{packageName}}{{/isGoSubmodule}}"
configuration := {{packageName}}.NewConfiguration()
configuration.Context = context.WithValue(configuration.Context, {{packageName}}.ContextOperationServerIndices, map[string]int{
"{classname}Service.{nickname}": 2,
})
configuration.Context = context.WithValue(configuration.Context, {{packageName}}.ContextOperationServerVariables, map[string]map[string]string{
"{classname}Service.{nickname}": {
"port": "8443",
},
})
```
## Getting Started

## Documentation for API Endpoints

Expand All @@ -97,134 +38,15 @@ Class | Method | HTTP request | Description
{{#models}}{{#model}} - [{{{classname}}}]({{modelDocPath}}{{{classname}}}.md)
{{/model}}{{/models}}

## Documentation For Authorization

{{^authMethods}} Endpoints do not require authorization.
{{/authMethods}}{{#authMethods}}{{#last}} Authentication schemes defined for the API:{{/last}}{{/authMethods}}
{{#authMethods}}

### {{{name}}}

{{#isApiKey}}
- **Type**: API key
- **API key parameter name**: {{{keyParamName}}}
- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}

Note, each API key must be added to a map of `map[string]APIKey` where the key is: "{{{name}}}" and passed in as the auth context for each request.

Example
## Proxy

```golang
import {{packageName}} "{{gitHost}}/{{gitUserId}}/{{gitRepoId}}{{#isGoSubmodule}}/{{packageName}}{{/isGoSubmodule}}"
apiKey := os.Getenv("API_KEY")
configuration := {{packageName}}.NewConfiguration()
configuration.Context = context.WithValue(configuration.Context, {{{packageName}}}.ContextAPIKeys, map[string]newscatcherapi.APIKey{
"{{{name}}}": {Key: apiKey}
})
client := {{packageName}}.NewAPIClient(configuration)
resp, httpRes, err := client.Service.Operation(args).Execute()
```

{{/isApiKey}}
{{#isBasic}}
{{#isBasicBearer}}
- **Type**: HTTP Bearer token authentication

Example

```golang
import {{packageName}} "{{gitHost}}/{{gitUserId}}/{{gitRepoId}}{{#isGoSubmodule}}/{{packageName}}{{/isGoSubmodule}}"
configuration := {{packageName}}.NewConfiguration()
configuration.Context = context.WithValue(configuration.Context, client.ContextAccessToken, "BEARER_TOKEN_STRING")
client := {{packageName}}.NewAPIClient(configuration)
resp, httpRes, err := client.Service.Operation(args).Execute()
```

{{/isBasicBearer}}
{{#isBasicBasic}}
- **Type**: HTTP basic authentication

Example

```golang
import {{packageName}} "{{gitHost}}/{{gitUserId}}/{{gitRepoId}}{{#isGoSubmodule}}/{{packageName}}{{/isGoSubmodule}}"
configuration := {{packageName}}.NewConfiguration()
configuration.Context = context.WithValue(configuration.Context, {{packageName}}.ContextBasicAuth, sw.BasicAuth{
UserName: "username",
Password: "password",
})
client := {{packageName}}.NewAPIClient(configuration)
resp, httpRes, err := client.Service.Operation(args).Execute()
```

{{/isBasicBasic}}
{{#isHttpSignature}}
- **Type**: HTTP signature authentication

Example

```golang
authConfig := client.HttpSignatureAuth{
KeyId: "my-key-id",
PrivateKeyPath: "rsa.pem",
Passphrase: "my-passphrase",
SigningScheme: sw.HttpSigningSchemeHs2019,
SignedHeaders: []string{
sw.HttpSignatureParameterRequestTarget, // The special (request-target) parameter expresses the HTTP request target.
sw.HttpSignatureParameterCreated, // Time when request was signed, formatted as a Unix timestamp integer value.
"Host", // The Host request header specifies the domain name of the server, and optionally the TCP port number.
"Date", // The date and time at which the message was originated.
"Content-Type", // The Media type of the body of the request.
"Digest", // A cryptographic digest of the request body.
},
SigningAlgorithm: sw.HttpSigningAlgorithmRsaPSS,
SignatureMaxValidity: 5 * time.Minute,
}
var authCtx context.Context
var err error
if authCtx, err = authConfig.ContextWithValue(context.Background()); err != nil {
// Process error
}
resp, httpRes, err = client.Service.Operation(args).Execute()

```
{{/isHttpSignature}}
{{/isBasic}}
{{#isOAuth}}

- **Type**: OAuth
- **Flow**: {{{flow}}}
- **Authorization URL**: {{{authorizationUrl}}}
- **Scopes**: {{^scopes}}N/A{{/scopes}}
{{#scopes}} - **{{{scope}}}**: {{{description}}}
{{/scopes}}

Example

```golang
import {{packageName}} "{{gitHost}}/{{gitUserId}}/{{gitRepoId}}{{#isGoSubmodule}}/{{packageName}}{{/isGoSubmodule}}"
configuration := {{packageName}}.NewConfiguration()
configuration.Context = context.WithValue(configuration.Context, sw.ContextAccessToken, "ACCESSTOKENSTRING")
client := {{packageName}}.NewAPIClient(configuration)
resp, httpRes, err := client.Service.Operation(args).Execute()
```

Or via OAuth2 module to automatically refresh tokens and perform user authentication.
To use a proxy, set the environment variable `HTTP_PROXY`:

```golang
/* Perform OAuth2 round trip request and obtain a token */
clientId := os.Getenv("CLIENT_ID")
clientSecret := os.Getenv("CLIENT_SECRET")
configuration := {{packageName}}.NewConfiguration()
configuration.SetOAuthClientCredentials(clientId, clientSecret)
client := {{packageName}}.NewAPIClient(configuration)
resp, httpRes, err := client.Service.Operation(args).Execute()
os.Setenv("HTTP_PROXY", "http://proxy_name:proxy_port")
```

{{/isOAuth}}
{{/authMethods}}

## Documentation for Utility Methods
## Utility Methods

Due to the fact that model structure members are all pointers, this package contains
a number of utility functions to easily obtain pointers to values of basic types.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ type {{#structPrefix}}{{&classname}}{{/structPrefix}}{{^structPrefix}}Api{{/stru
{{#isDeprecated}}
// Deprecated
{{/isDeprecated}}
func (r {{#structPrefix}}{{&classname}}{{/structPrefix}}{{^structPrefix}}Api{{/structPrefix}}{{operationId}}Request) {{vendorExtensions.x-export-param-name}}({{paramName}} {{{dataType}}}) {{#structPrefix}}{{&classname}}{{/structPrefix}}{{^structPrefix}}Api{{/structPrefix}}{{operationId}}Request {
func (r *{{#structPrefix}}{{&classname}}{{/structPrefix}}{{^structPrefix}}Api{{/structPrefix}}{{operationId}}Request) {{vendorExtensions.x-export-param-name}}({{paramName}} {{{dataType}}}) *{{#structPrefix}}{{&classname}}{{/structPrefix}}{{^structPrefix}}Api{{/structPrefix}}{{operationId}}Request {
r.{{paramName}} = &{{paramName}}
return r
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{#isString}}"{{example}}"{{/isString}}{{^isString}}{{>api_doc_example_param_non_string_example}}{{/isString}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{#isBinary}}emptyFile(t){{/isBinary}}{{^isBinary}}{{#isBodyParam}}{{paramName}}{{/isBodyParam}}{{^isBodyParam}}{{example}}{{/isBodyParam}}{{/isBinary}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{#allParams}}
{{#isBodyParam}}
{{paramName}} := *{{goImportAlias}}.New{{dataType}}(
{{#requiredVars}}
{{> api_doc_example_param_example}},
{{/requiredVars}}
)
{{#optionalVars}}
{{paramName}}.Set{{name}}({{> api_doc_example_param_example}})
{{/optionalVars}}
{{/isBodyParam}}
request.{{paramNameCamelCaseUpper}}({{> api_doc_example_param_example}})
{{/allParams}}
Original file line number Diff line number Diff line change
Expand Up @@ -7,50 +7,39 @@ Testing {{classname}}Service

*/

{{^removeKonfigBranding}}
// Code generated by Konfig (https://konfigthis.com);
{{/removeKonfigBranding}}

package {{packageName}}

import ({{#authMethods}}{{#-first}}{{#isApiKey}}
import (
"os"
"context"{{/isApiKey}}{{/-first}}{{/authMethods}}
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"testing"
{{goImportAlias}} "{{gitHost}}/{{gitUserId}}/{{gitRepoId}}{{#isGoSubmodule}}/{{packageName}}{{/isGoSubmodule}}"
)

func Test_{{packageName}}_{{classname}}Service(t *testing.T) {
configuration := {{goImportAlias}}.NewConfiguration()
{{#hasAuthMethods}}
{{#authMethods}}{{#-first}}
configuration.SetHost("http://127.0.0.1:4010")
{{#authMethods}}
{{#isApiKey}}
apiKey := os.Getenv("API_KEY")
configuration.Context = context.WithValue(configuration.Context, {{goImportAlias}}.ContextAPIKeys, map[string]{{goImportAlias}}.APIKey{
"{{name}}": {Key: apiKey},
})
configuration.Set{{nameInCamelCase}}("{{keyParamNameSnakeCaseUppercase}}")
{{/isApiKey}}
{{/-first}}{{/authMethods}}
{{/hasAuthMethods}}
apiClient := {{goImportAlias}}.NewAPIClient(configuration)
{{/authMethods}}
client := {{goImportAlias}}.NewAPIClient(configuration)

{{#operations}}
{{#operation}}
t.Run("Test {{classname}}Service {{{nickname}}}", func(t *testing.T) {
{{^pathParams}}
t.Skip("skip test") // remove to run test
{{/pathParams}}
{{#pathParams}}
{{#-first}}
t.Skip("skip test") // remove to run test
request := client.{{classname}}.{{operationId}}()
{{> api_doc_example_params}}

{{/-first}}
var {{paramName}} {{{dataType}}}
{{/pathParams}}

resp, httpRes, err := apiClient.{{classname}}.{{operationId}}({{#pathParams}}{{paramName}}{{^-last}}, {{/-last}}{{/pathParams}}).Execute()
resp, httpRes, err := request.Execute()

require.Nil(t, err)
require.NotNil(t, resp)
Expand All @@ -61,3 +50,14 @@ func Test_{{packageName}}_{{classname}}Service(t *testing.T) {
{{/operation}}
{{/operations}}
}

func emptyFile(t *testing.T) *os.File {
tempFile, err := os.CreateTemp("", "empty-file")
if err != nil {
t.Fatal(err) // Fail the test if we can't create the temporary file
}
t.Cleanup(func() {
os.Remove(tempFile.Name()) // Clean up the file after the test
})
return tempFile
}
Loading

0 comments on commit 47828bc

Please sign in to comment.