Code Monkey home page Code Monkey logo

gnostic-go-generator's Introduction

gnostic Go Generator Plugin

This project contains a gnostic plugin that can be used to generate a Go client library and scaffolding for a Go server for an API with an OpenAPI description.

The plugin can be invoked like this:

gnostic bookstore.json --go-generator-out=bookstore

bookstore is the name of a directory where the generated code will be written. bookstore will also be the package name used for generated code.

By default, both client and server code will be generated. If the gnostic-go-generator binary is also linked from the names gnostic-go-client and gnostic-go-server, then only client or only server code can be generated as follows:

gnostic bookstore.json --go-client-out=bookstore

gnostic bookstore.json --go-server-out=bookstore

For example usage, see the examples/v2.0/bookstore directory.

Disclaimer

This is not an officially supported Google product

gnostic-go-generator's People

Contributors

bvwells avatar checorone avatar glickbot avatar justinbeckwith avatar lorenzhw avatar noahdietz avatar timburks avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

gnostic-go-generator's Issues

More robust identifier parsing?

This would fix #8 #6 in a more robust way

  • prefix any starting number with a 'n'
  • replace any non-unicode letter with either '_' or an empty string.

If they're done in that order and if non-unicode letters are replaced with an empty string, it would handle fields that start with non-unicode letters and numbers. Like this:

https://play.golang.org/p/yyG0XUihd59

package main

import (
	"fmt"
	"regexp"
)

const crazyFieldName = "$12t-his@is_Crazy#(*Æ"

func main() {
	decimalStart := regexp.MustCompile(`^\W*\d+`)
	replaceCrazy := regexp.MustCompile(`\W`)
	fixednum := decimalStart.ReplaceAllStringFunc(crazyFieldName, numFix)
	fixed := replaceCrazy.ReplaceAllStringFunc(fixednum, charFix)
	fmt.Println(fixed)
}

func numFix(match string) string {
	fmt.Printf("Number Fix: %s\n", match)
	return fmt.Sprintf("n%s", match)
}

func charFix(match string) string {
	fmt.Printf("Found %s\n", match)
	return ""
}

Number Fix: $12
Found $
Found -
Found @
Found #
Found (
Found *
Found Æ
n12thisis_Crazy

IMO it'd be great if we could let the user decide what they want replaced by using something like https://github.com/spf13/viper. It would allow them to use flags for most options, but could allow further customization if the user needs something more elaborate (i.e. replacing entire field names in case they don't like myType, etc). This would minimize hand-tweaking of the resulting code.

Thoughts? I can put a PR in unless you'd rather not have a dependency like spf13/viper.

"any" type isn't handled

Plugin doesn't handle the 'any' type (which currently isn't handled by the model yet either). (same issue as: google/gnostic#125)

disco get bigquery v2 --openapi3
gnostic openapi3-bigquery-v2.pb --go-client-out=bigquery
2019/05/23 15:38:53 unimplemented: type:"any"

PR for gnostic + gnostic-go-plugin, I need to add this modification to this plugin when/if the model can handle the 'any' type:
google/gnostic#126

Error with '@' in field name

The '@' should be escaped in field names
example:
disco get kgsearch v1 --openapi3 && gnostic openapi3-kgsearch-v1.pb --go-client-out=kgsearch
Errors reading openapi3-kgsearch-v1.pb
Plugin error: [types.go:7:1: illegal character U+0040 '@' (and 1 more errors)]

Non-200 responses treated as errors in client

Non-200 responses are being treated as errors in generated clients, i.e.

	if resp.StatusCode != 200 {
		return nil, errors.New(resp.Status)
	}

It would be nice to handle other 2xx response codes as success, e.g. 202 Accepted.

Enable master branch protection

      This repository does not seem to have master branch
      protection enabled, at least in the way I'm expecting.
      I was hoping for:

      - master branch protection
      - requiring at least one code reviewer
      - requiring at least two status checks
      - enforcing rules for admins

      Please turn it on!

Errors with '$' in field name

Normal '$ref' fields are handled, but for APIs that define fields that are called '$ref', it tries to use '$ref' as the identifier, which throws an error:

disco get discovery v1 --openapi3 && gnostic openapi3-discovery-v1.pb --go-client-out=discovery
Errors reading openapi3-discovery-v1.pb
Plugin error: [types.go:13:1: illegal character U+0024 '$']

imports error: expected 'IDENT', found 'if'

not sure what it means yet, but the example is:
disco get android_video v1 --openapi3 && gnostic openapi3-android_video-v1.pb --go-client-out=androidvideo
Errors reading openapi3-android_video-v1.pb
Plugin error: [client.go:59:1: expected 'IDENT', found 'if' (and 8 more errors)]

Bind Parameters to Request suffix

Currently parameters are converted to an object with suffix Parameters.
Proposing if we can change this behaviour to

  1. If its 1 parameter, pass it directly to rpc method args
  2. Or add a Request suffix. Its seems more natural to understand.
"/pay/v1/transactions/{transactionId}/callback/pgs/payu": {
      "post": {
        "tags": [
          "callback-controller"
        ],
        "operationId": "payU",
        "parameters": [
          {
            "name": "transactionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "default response"
          }
        }
      }
    }

creates

 rpc PayU ( PayUParameters ) returns ( google.protobuf.Empty ) {
    option (google.api.http) = { post:"/pay/v1/transactions/{transactionId}/callback/pgs/payu"  };
  }

Excepcted

 rpc PayU ( string ) returns ( google.protobuf.Empty ) {
    option (google.api.http) = { post:"/pay/v1/transactions/{transactionId}/callback/pgs/payu"  };
  }

OR

 rpc PayU ( PayURequest ) returns ( google.protobuf.Empty ) {
    option (google.api.http) = { post:"/pay/v1/transactions/{transactionId}/callback/pgs/payu"  };
  }

additionalProperties wrong map type

Hi,

In Swagger model I have following construct:

someAttributes:
        type: object
        description: someAttributes
        additionalProperties:
          type: string

Then I'm trying to build this model with gnostic-go-generator it produces below model

{
      "name": "someAttributes",
      "fields": [
        {
          "name": "additional_properties",
          "type": "map[string]string",
          "kind": 1,
          "native_type": "Map[String]String",
          "field_name": "AdditionalProperties",
          "parameter_name": "additional_properties"
        }
      ],
      "type_name": "SomeAttributes"
    },

Type Map[String]String is invalid in Go, so it results in broken types.go file

Get an incomprehensible error on generation

I am trying to generate Go code from an OpenAPI 3 file and it just crash. I don't have any hint. Someone can help me (it does the same when I use the local file) ?

gnostic --resolve-refs --go-generator-out=./gen https://raw.githubusercontent.com/Terminal49/t49-api-documentation/master/docs/reference/terminal49/terminal49.v1.json
Errors reading https://raw.githubusercontent.com/Terminal49/t49-api-documentation/master/docs/reference/terminal49/terminal49.v1.json
Plugin error: [client.go:24:26: expected '(', found '-' (and 4 more errors) server.go:28:15: expected '(', found '-' (and 10 more errors) provider.go:14:4: expected ';', found '-' (and 1 more errors) types.go:226:9: expected type, found '-' (and 10 more errors)]

Add context to Provider interface

It would be nice if the generated Provider interface would mimic what gRPC does and add a default ctx context.Context as the first argument.

// inside `provider.go`
type Provider interface {
    GetSomething(ctx context.Context, responses *GetSomethingResponses) (err error)
}

// and then in the Handler, simply use the context from the incoming request
// inside `server.go`
func HandleGetSomething(w http.ResponseWriter, r *http.Request) {
    // ... stuff
    err = provider.GetSomething(r.Context(), responses)
    // ... more stuff
}

This would allow passing context from an http.Client, or protecting your handler with a TimeoutMiddleware:

func TimeoutMiddleware(next http.Handler) http.Handler {
	timeout := 7 * time.Second
	msg := `{"error":  "your request timed out"}`
	return http.TimeoutHandler(next, timeout, msg)
}

Polymorphism doesn't work correctly

Something like

"UPI": {
        "type": "object",
        "allOf": [
          {
            "$ref": "#/components/schemas/PaymentMode"
          },
          {
            "type": "object",
            "properties": {
              "vpa": {
                "type": "string"
              },
              "status": {
                "type": "string"
              }
            }
          }
        ]
      }

Generates

message UPIAllOf2 {
  string vpa = 1;

  string status = 2;
}

message UPI {
  PaymentMode all_of_1 = 1;

  UPIAllOf2 all_of_2 = 2;
}

In place of

message UPI {
  PaymentMode mode = 1;
  string vpa = 1;
  string status = 2;
}

Code generation for OpenAPI v3 doesn't seem to work at all

From the examples:

$ gnostic bookstore.json --go-generator-out=bookstore
Errors reading bookstore.json
Plugin error: [types.go:31:12: expected ';', found '/' (and 10 more errors)]
Plugin error: [types.go:31:12: expected ';', found '/' (and 10 more errors)]

Doesn't seem to work for any other openapi v3 definitions I have on hand.

Add context to client interface

It would be good to have a context passed in the generated client methods so that it become easier to add timeouts/deadlines to the requests. i.e.

func (client *Client) DeleteShelves() error {
...

becomes

func (client *Client) DeleteShelves(ctx context.Context) error {
...

This issue related to #24.

Body for non-200 responses get lost

Many APIs return a payload in the case of a non-200 response. For example, an error payload with details of why an API call was a bad request. i.e.

        '400':
          description: Bad request
          schema:
            $ref: "#/definitions/error"

It would be useful to have these payloads returned from the generated clients.

enums are converted to string

The generator fails to translate enum in schem to enum in proto.

e.g.

"TransactionStatusResponse": {
        "type": "object",
        "properties": {
          "transactionStatus": {
            "type": "string",
            "enum": [
              "SUCCESS",
              "FAILURE",
              "PROCESSING",
              "INITIATED"
            ]
          },
          "transactionDate": {
            "type": "string",
            "format": "date-time"
          }
        }
      },

generates

message TransactionStatusResponse {
  string transaction_status = 1;

  string transaction_date = 2;
}

and omits enum completely.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.