Skip to content

[Go] Rewrite of Go Client, Server generator #5037

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

Merged
merged 8 commits into from
Apr 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion bin/go-petstore-server.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ fi

# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l go-server -o samples/server/petstore/go-api-server -DpackageName=petstoreserver --additional-properties hideGenerationTimestamp=true "

ags="$@ generate -t modules/swagger-codegen/src/main/resources/go-server -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l go-server -o samples/server/petstore/go-api-server -DpackageName=petstoreserver --additional-properties hideGenerationTimestamp=true"

java $JAVA_OPTS -Dservice -jar $executable $ags
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public GoClientCodegen() {
typeMapping.put("boolean", "bool");
typeMapping.put("string", "string");
typeMapping.put("UUID", "string");
typeMapping.put("date", "time.Time");
typeMapping.put("date", "string");
typeMapping.put("DateTime", "time.Time");
typeMapping.put("password", "string");
typeMapping.put("File", "*os.File");
Expand Down Expand Up @@ -274,8 +274,6 @@ public String toApiFilename(String name) {
return underscore(name) + "_api";
}



/**
* Overrides postProcessParameter to add a vendor extension "x-exportParamName".
* This is useful when paramName starts with a lowercase letter, but we need that
Expand Down Expand Up @@ -303,7 +301,6 @@ public void postProcessParameter(CodegenParameter parameter){
parameter.vendorExtensions.put("x-exportParamName", sb.toString());
}


@Override
public String apiDocFileFolder() {
return (outputFolder + "/" + apiDocPath).replace('/', File.separatorChar);
Expand Down Expand Up @@ -406,9 +403,10 @@ public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
if (_import.startsWith(apiPackage()))
iterator.remove();
}
// if the return type is not primitive, import encoding/json

// if their is a return type, import encoding/json
for (CodegenOperation operation : operations) {
if(operation.returnBaseType != null && needToImport(operation.returnBaseType)) {
if(operation.returnBaseType != null ) {
imports.add(createMapping("import", "encoding/json"));
break; //just need to import once
}
Expand All @@ -422,7 +420,6 @@ public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
}
}


// recursively add import for mapping one type to multiple imports
List<Map<String, String>> recursiveImports = (List<Map<String, String>>) objs.get("imports");
if (recursiveImports == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
import io.swagger.codegen.*;
import io.swagger.models.*;
import io.swagger.util.Yaml;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.parameters.Parameter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -64,6 +69,11 @@ public GoServerCodegen() {
*/
setReservedWordsLowerCase(
Arrays.asList(
// data type
"string", "bool", "uint", "uint8", "uint16", "uint32", "uint64",
"int", "int8", "int16", "int32", "int64", "float32", "float64",
"complex64", "complex128", "rune", "byte", "uintptr",

"break", "default", "func", "interface", "select",
"case", "defer", "go", "map", "struct",
"chan", "else", "goto", "package", "switch",
Expand Down Expand Up @@ -108,7 +118,8 @@ public GoServerCodegen() {
typeMapping.put("double", "float64");
typeMapping.put("boolean", "bool");
typeMapping.put("string", "string");
typeMapping.put("date", "time.Time");
typeMapping.put("UUID", "string");
typeMapping.put("date", "string");
typeMapping.put("DateTime", "time.Time");
typeMapping.put("password", "string");
typeMapping.put("File", "*os.File");
Expand All @@ -117,6 +128,7 @@ public GoServerCodegen() {
// the correct solution is to use []byte
typeMapping.put("binary", "string");
typeMapping.put("ByteArray", "string");
typeMapping.put("object", "interface{}");

importMapping = new HashMap<String, String>();
importMapping.put("time.Time", "time");
Expand Down Expand Up @@ -243,11 +255,11 @@ public String toOperationId(String operationId) {
@Override
public String toModelFilename(String name) {
if (!StringUtils.isEmpty(modelNamePrefix)) {
name = modelNamePrefix + "_" + name;
name = modelNamePrefix + name;
}

if (!StringUtils.isEmpty(modelNameSuffix)) {
name = name + "_" + modelNameSuffix;
name = name + modelNameSuffix;
}

name = sanitizeName(name);
Expand All @@ -258,7 +270,54 @@ public String toModelFilename(String name) {
name = "model_" + name; // e.g. return => ModelReturn (after camelize)
}

return underscore(name);
return camelize(name);
}

@Override
public String getTypeDeclaration(Property p) {
if(p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return "[]" + getTypeDeclaration(inner);
}
else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();

return getSwaggerType(p) + "[string]" + getTypeDeclaration(inner);
}
//return super.getTypeDeclaration(p);

// Not using the supertype invocation, because we want to UpperCamelize
// the type.
String swaggerType = getSwaggerType(p);
if (typeMapping.containsKey(swaggerType)) {
return typeMapping.get(swaggerType);
}

if(typeMapping.containsValue(swaggerType)) {
return swaggerType;
}

if(languageSpecificPrimitives.contains(swaggerType)) {
return swaggerType;
}

return toModelName(swaggerType);
}

@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
String type = null;
if(typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
if(languageSpecificPrimitives.contains(type))
return (type);
}
else
type = swaggerType;
return type;
}

@Override
Expand Down
45 changes: 38 additions & 7 deletions modules/swagger-codegen/src/main/resources/go/README.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,56 @@ Class | Method | HTTP request | Description
{{/model}}{{/models}}

## Documentation For Authorization

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

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

Example
```
auth := context.WithValue(context.TODO(), sw.ContextAPIKey, sw.APIKey{
Key: "APIKEY",
Prefix: "Bearer", // Omit if not necessary.
})
r, err := client.Service.Operation(auth, args)
```
{{/isApiKey}}
{{#isBasic}}- **Type**: HTTP basic authentication

Example
```
auth := context.WithValue(context.TODO(), sw.ContextBasicAuth, sw.BasicAuth{
UserName: "username",
Password: "password",
})
r, err := client.Service.Operation(auth, args)
```
{{/isBasic}}
{{#isOAuth}}- **Type**: OAuth
- **Flow**: {{{flow}}}
- **Authorization URL**: {{{authorizationUrl}}}
- **Scopes**: {{^scopes}}N/A{{/scopes}}
{{#scopes}} - **{{{scope}}}**: {{{description}}}
{{/scopes}}
{{/isOAuth}}

Example
```
auth := context.WithValue(context.TODO(), sw.ContextAccessToken, "ACCESSTOKENSTRING")
r, err := client.Service.Operation(auth, args)
```

Or via OAuth2 module to automaticly refresh tokens and perform user authentication.
```
import "golang.org/x/oauth2"

/ .. Perform OAuth2 round trip request and obtain a token .. //

tokenSource := oauth2cfg.TokenSource(createContext(httpClient), &token)
auth := context.WithValue(oauth2.NoContext, sw.ContextOAuth2, tokenSource)
r, err := client.Service.Operation(auth, args)
```
{{/isOAuth}}
{{/authMethods}}

## Author
Expand Down
Loading