GithubHelp home page GithubHelp logo

mikekonan / go-oas3 Goto Github PK

View Code? Open in Web Editor NEW
20.0 3.0 9.0 173 KB

Open API v3 server code generator

License: MIT License

Go 100.00%
swagger openapi3 swagger-codegen oas3 openapi-generator rest rest-api codegenerator openapi

go-oas3's Introduction

Go OpenAPI v3 server codegenerator

The purpose of this project is to generate a clean server boilerplate code from openapi v3 specification. The generated code based on github.com/go-chi/chi/v5 router. Generator goes over all paths and components and generates Go structs and stubs.

Key ideas:

  • Stubs take over the logic of parsing the request.
  • Response builders encapsulated logic that doesn't allow you to respond differently from your specification.

Take a note that path stubs generation relies on the first tag from your paths.

Installation

go install github.com/mikekonan/go-oas3@latest

Program arguments

Usage of go-oas3:
  -componentsPackage string
  -componentsPath string
  -package string
  -path string
  -swagger-addr string
    	 (default "swagger.yaml")
  -authorization string 
    a list of comma-separated key:value pairs to be sent as headers alongside each http request
  -prioritize-x-go-type
    by default, if both properties and x-go-type is provided, the generator will use properties.
    this flag will make generator prioritize x-go-type over properties.

Example

Run with: go-oas3 -swagger-addr https://raw.githubusercontent.com/mikekonan/go-oas3/v1.0.54/example/swagger.yaml -package example -path ./example The result generated boilerplate and its client you can see at ./example.

OpenAPI features

Required fields

Path, query, component, header required fields are supported.

Security

Security schemas for http, apikey (header/cookie).

Cookie

Response header Set-Cookie supported. Cookie in request supported via security schema only.

Validation

Types validation supports following data types:

  • string: minLength, maxLength
  • number, integer: minimum, maximum, exclusiveMinimum, exclusiveMaximum

Custom types

Generator supports few swagger types for components.

openapi type go type
uuid github.com/google/uuid.UUID
iso4217-currency-code github.com/mikekonan/go-types/v2/currency.Code
iso3166-alpha-2 github.com/mikekonan/go-types/v2/country.Alpha2Code
iso3166-alpha-3 github.com/mikekonan/go-types/v2/country.Alpha3Code

Extentions:

Specify a go type with:

    Component:
      properties:
        metadata:
          type: object
          x-go-type: encoding/json.RawMessage

Forcing pointer usage for the field:

    Component:
      properties:
        amount:
          type: int
          x-go-pointer: true

Specify a regex to match a string:

    Parameter:
      description: Parameter
      in: header
      name: parameter name
      required: true
      schema:
        type: string
        x-go-regex: ^[.?\d]+$

If you want to use your specific type(it has to declare function Parse{TYPENAME} ({TYPENAME}, error)) in query/path/header params:

    TYPENAME:
      type: string
      x-go-type: githubrepo/lib/pkg.{TYPENAME}
      x-go-type-string-parse: githubrepo/lib/pkg.Parse{TYPENAME}

If you want to have a specific go map you can also use x-go-type to specify a key. It works only if additionalProperties specified.

    ResponseBody:
      type: object
      additionalProperties:
        items:
          $ref: '#/components/schemas/objects.Type'
        type: array
      x-go-type: githubrepo/objects.SomeType

Use x-go-string-timmable key If you would like to trim spaces before validation. It works only for string type

    ResponseBody:
      properties:
        title:
          type: string
          x-go-string-trimmable: true

If you want to add omitempty tag you can also use x-go-omitempty

    ResponseBody:
      properties:
        title:
          type: string
          x-go-omitempty: true

By default, validation is added to request body objects. If you want to ignore validation, use flag x-go-skip-validation

    ResponseBody:
      properties:
        title:
          type: string
      x-go-skip-validation: true

Have a question or need some functionality?

Feel free to discuss it or do a PR.

Contribution

Go OpenAPI v3 server codegenerator uses https://github.com/dave/jennifer. Using https://github.com/aloder/tojen is suggested way to generate jennifer code.

go-oas3's People

Contributors

asechiho avatar daniil-pankratov avatar glebbeloded avatar konstantsiy avatar lstmix avatar mikekonan avatar sergeydobrodey avatar vadim-mve avatar valichek avatar

Stargazers

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

Watchers

 avatar  avatar  avatar

go-oas3's Issues

Schema type with enum property leads to broken code

Schema type (1) with enum property is translated to code (2) with intermediate type schemaTypeTypeEnum which is not defined.

Workaround: enum can be declared as separate schema type and referenced (3)

    SchemaType:
      properties:
        type:
          type: string
          enum: [ value1 value2]
type schemaType struct {
	Type schemaTypeTypeEnum `json:"type"`
}

type SchemaType struct {
	Type SchemaTypeTypeEnum `json:"type"`
}
    SchemaType:
      properties:
        type:
          $ref: '#/components/schemas/SchemaTypeFieldEnum'
    SchemaTypeFieldEnum:
      type: string
      enum: [ value1 value2 ]

同学,您这个项目引入了155个开源组件,存在3个漏洞,辛苦升级一下

检测到 mikekonan/go-oas3 一共引入了155个开源组件,存在3个漏洞

漏洞标题:jwt-go 安全漏洞
缺陷组件:github.com/dgrijalva/[email protected]+incompatible
漏洞编号:CVE-2020-26160
漏洞描述:jwt-go是个人开发者的一个Go语言的JWT实现。
jwt-go 4.0.0-preview1之前版本存在安全漏洞。攻击者可利用该漏洞在使用[]string{} for m[\"aud\"](规范允许)的情况下绕过预期的访问限制。
影响范围:(∞, 4.0.0-preview1)
最小修复版本:4.0.0-preview1
缺陷组件引入路径:github.com/mikekonan/go-oas3@->github.com/dgrijalva/[email protected]+incompatible

另外还有3个漏洞,详细报告:https://mofeisec.com/jr?p=afff1b

Provide access to gen.ErrorResponseBody via hook

There must be easy way to access data from handler (like error) in hook.
It can be ResponseBodyWriteCompleted hook with signature func(request *http.Request, handlerName string, bytesWritten int, statusCode int, body interface{})
Maybe it would be more general also to pass context from handler to the hook.

builder.StatusCode400().ApplicationJson().Body(responseBody).Build(ctx)

Field order in generated structures

Currently generated structs have their fields in alphabetic order, it would be nice if fields of go structure were declared in order in which they are declared in the specification.

Error when setting x-go-regex in component schema

Generation of swagger example with:

CreateTransactionRequest:
      properties:
        Currency:
          $ref: '#/components/schemas/CurrencyCode'
        Country:
          $ref: '#/components/schemas/CountryAlpha2'
        Email:
          $ref: '#/components/schemas/Email'
        CallbackURL:
          $ref: '#/components/schemas/URL'
        TransactionID:
          type: string
          format: uuid
        RegexParam:
          type: string
          x-go-regex: ^[.?\d]+$ # added this line

results to error:
Error 73:3: expected ';', found body while formatting source:

Redeclared headers struct

In case when response has only headers, but no content, generator output contains redeclared structure

entrypoint/processing/v1/gen/routes_gen.go:2101:6: PutOperationsUUID200Headers redeclared in this block
        previous declaration at entrypoint/processing/v1/gen/routes_gen.go:2092:6
entrypoint/processing/v1/gen/routes_gen.go:2105:44: PutOperationsUUID200Headers.toMap redeclared in this block
        previous declaration at entrypoint/processing/v1/gen/routes_gen.go:2096:6
paths:
  '/operations/{uuid}':
    put:
      responses:
        '200':
          headers:
            x-jws-signature:
              schema:
                type: string
              description: response signature
          description: OK

BTW:
generated header name is incorrect XJwsSignature, but should be x-jws-signature

type PutOperationsUUID200Headers struct {
	XJwsSignature string
}

func (headers PutOperationsUUID200Headers) toMap() map[string]string {

	return map[string]string{"XJwsSignature": cast.ToString(headers.XJwsSignature)}
}

Need to implement "required" attribute for slices

SessionExtended:
      properties:
        permissions:
          items:
            type: string
          type: array
        session:
          $ref: "#/components/schemas/Session"
          type: object
        unitAccessRights:
          items:
            $ref: "#/components/schemas/UnitAccessRecord"
          type: array
        user:
          $ref: "#/components/schemas/User"
          type: object
      required:
        - permissions
        - session
        - unitAccessRights
        - user
      type: object
go generate ./...
GOPRIVATE="xdevteam.com/*" go get ./...
# api/entrypoint/backoffice/v1/gen
entrypoint/backoffice/v1/gen/components_gen.go:283:19: cannot use *value.Permissions (type []*string) as type []string in assignment
entrypoint/backoffice/v1/gen/components_gen.go:295:24: cannot use *value.UnitAccessRights (type []*UnitAccessRecord) as type []UnitAccessRecord in assignment
make: *** [prepare] Error 2

Incorrect interface generated when using OneOf from a remote schema

When using schema in the example, type FooKek is generate as:
type FooKek FooKek

This is happening because remote schema is a oneOf consisting only of refs. If those refs were defined locally, normal go code would be generated.

Example schema:

openapi: 3.0.3

info:
  title: KekBek
  version: 1.0.0

components:
  schemas:
    FooKek:
      $ref: "https://pastebin.com/raw/caMMBFjS#/components/schemas/FooKek"

And remote schema is:

openapi: 3.0.3

info:
  title: KekBek
  version: 1.0.0

components:
  schemas:
    Foo:
      type: object
      properties:
        Bar:
          type: string

    Kek:
      type: object
      properties:
        Bek:
          type: string

    FooKek:
      oneOf:
        - $ref: "#/components/schemas/Foo"
        - $ref: "#/components/schemas/Kek"

Incorrect go code generated

Hello,

I read about this project in go subredit and I like the idea of go generator from swagger.
I tried to check it on a little bit complicated API (https://openapi3.ocs.io/browse/index.html) I have to deal with (I'm not an author of API, just consumer).

go run . -swagger-addr https://openapi3.ocs.io/ocs-io-openapi3.yaml -package example -path ./example

It fails with:

2021/05/06 09:26:14 failed rending into file '/Users/simoniki/tmp/go-oas3/example/routes_gen.go': Error 73:10: expected '(', found '-' (and 10 more errors) while formatting source:
// This file is generated by github.com/mikekonan/go-oas3. DO NOT EDIT.

package example

import (
"context"
"encoding/json"
"encoding/xml"
"errors"
"fmt"
chi "github.com/go-chi/chi"
cast "github.com/spf13/cast"
"net/http"
)

[snip]

The output is not quite clear (because it failed during formatting operation, but the generated code printed on stdout is suspicious. For example:

 func RM - DocumentsHandler (impl RM - DocumentsService,r chi.Router,hooks * Hooks) (http.Handler) {
router := & rm - documentsRouter {router : r,service : impl,hooks : hooks}

 router . mount ()

 return  router . router
}

For the first sight it looks like using the first item from "tags" as the name of function without sanitizing. Is it good idea to use tags for names?

And maybe one more question: I usually use generators only for DTOs. The openapi-tool generator has the option to generate only model, without router. I think it should be fine to have the same option here as well. Sometimes go-chi is not desired router or other reason.

Problem with component schema type customising

Schema top level object (defined below) with x-go-type tag is translated to type Credentials fbk.JSONObjectRaw, so custom json.Marshaler json.Unmarshaler implementation are not used and Credentials behaves like []byte. I think type aliasing should be used: type Credentials = fbk.JSONObjectRaw

Credentials:
      type: object
      x-go-type: "xdevteam.com/pa/lib/fbk.JSONObjectRaw"     

Invalid type alias generated for handling special types like currency.Code

When using reference for a schema instead of describing request parameters explicitly, CustomType is generated instead of using currency.Code enum

openapi: 3.0.0
info:
  description: Kek API
  title: Kek API
  contact: { }
  license:
    name: DRAFT
  version: 0.0.1

servers:
  - url: /v1

paths:
  /foo:
    get:
      tags:
        - kek
      parameters:
        - name: CurrencyCodeBar
          in: header
          schema:
            $ref: "#/components/schemas/CurrencyCodeFoo"
      responses:
        200:
          description: OK

  /bar:
    get:
      tags:
        - kek
      responses:
        200:
          description: OK
      parameters:
        - name: CurrencyCodeBar
          in: header
          schema:
            example: EUR
            type: string
            format: iso4217-currency-code

components:
  parameters:
    CurrencyCode:
      name: CurrencyCode
      in: header
      schema:
        $ref: "#/components/schemas/CurrencyCodeFoo"

  schemas:
    CurrencyCodeFoo:
      example: EUR
      type: string
      format: iso4217-currency-code

Generating map[string]Struct from OpenAPI spec "additionalProperties"

Using spec

Template:
 properties:
   endpoints:
     additionalProperties:
       $ref: "#/components/schemas/Endpoint"
     type: object

should generate

type Template struct {
   Endpoints map[string]Endpoint `json:"endpoints"`
}

instead of

type Template struct {
   Endpoints interface{} `json:"endpoints"`
}

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.