Code Monkey home page Code Monkey logo

kok's Introduction

kok

The toolkit of Go kit.

Zen

  • Just write code for your business logic, generate everything else.
  • Implement the service once, consume it in various ways (in-process function call or RPC).

Features

  1. Code Generation Tool

    • Endpoint
    • Transport
      • HTTP
        • HTTP Server
        • HTTP Test
        • HTTP Client
        • OAS-v2 Documentation
      • gRPC
  2. Useful Packages

    • appx: Application framework for HTTP and CRON applications (a wrapper of appx).
    • prometheus: Prometheus metrics utilities.
    • trace: A thin wrapper of x/net/trace for Go kit.
    • werror: Classified business errors.

Installation

$ go get -u github.com/RussellLuo/kok/cmd/kokgen
Usage
$ kokgen -h
kokgen [flags] source-file interface-name
  -fmt
    	whether to make code formatted (default true)
  -out string
    	output directory (default ".")
  -pkg string
    	package name (default will infer)
  -test string
    	the YAML file that provides test-cases for HTTP (default "./http.test.yaml")
  -trace
    	whether to enable tracing

Quick Start

NOTE: The following code is located in helloworld.

  1. Define the interface

    type Service interface {
        SayHello(ctx context.Context, name string) (message string, err error)
    }
  2. Implement the service

    type Greeter struct{}
    
    func (g *Greeter) SayHello(ctx context.Context, name string) (string, error) {
        return "Hello " + name, nil
    }
  3. Add HTTP annotations

    type Service interface {
        // @kok(op): POST /messages
        SayHello(ctx context.Context, name string) (message string, err error)
    }
  4. Generate the HTTP code

    $ cd examples/helloworld
    $ kokgen ./service.go Service
  5. Consume the service

    Run the HTTP server:

    $ go run cmd/main.go
    2020/09/15 18:06:22 transport=HTTP addr=:8080

    Consume by HTTPie:

    $ http POST :8080/messages name=Tracey
    HTTP/1.1 200 OK
    Content-Length: 27
    Content-Type: application/json; charset=utf-8
    Date: Tue, 15 Sep 2020 10:06:34 GMT
    
    {
        "message": "Hello Tracey"
    }
  6. See the OAS documentation

    (Click to show details)
    $ http GET :8080/api
    HTTP/1.1 200 OK
    Content-Length: 848
    Content-Type: text/plain; charset=utf-8
    Date: Tue, 15 Sep 2020 10:08:24 GMT
    
    swagger: "2.0"
    info:
      version: "1.0.0"
      title: "Swagger Example"
      description: ""
      license:
        name: "MIT"
    host: "example.com"
    basePath: "/api"
    schemes:
      - "https"
    consumes:
      - "application/json"
    produces:
      - "application/json"
    
    paths:
      /messages:
        post:
          description: ""
          operationId: "SayHello"
          parameters:
            - name: body
              in: body
              schema:
                $ref: "#/definitions/SayHelloRequestBody"
    
          produces:
            - application/json; charset=utf-8
          responses:
            200:
              description: ""
              schema:
                $ref: "#/definitions/SayHelloResponse"
    
    
    definitions:
      SayHelloRequestBody:
        type: object
        properties:
          name:
            type: string
      SayHelloResponse:
        type: object
        properties:
          message:
            type: string

See more examples here.

HTTP

Annotations

Define the HTTP request operation
  • Key: @kok(op)

  • Value: <method> <pattern>

    • method: The request method
    • pattern: The request URL
      • NOTE: All variables (snake-case or camel-case) in pattern will automatically be bound to their corresponding method arguments (matches by name), as path parameters, if the variables are not specified as path parameters explicitly by @kok(param).
  • Example:

    type Service interface {
        // @kok(op): DELETE /users/{id}
        DeleteUser(ctx context.Context, id int) (err error)
    }
    
    // HTTP request:
    // $ http DELETE /users/101
Define the HTTP request parameters
  • Key: @kok(param)
  • Value: <argName> < in:<in>,name:<name>,type:<type>,required:<required>
    • argName: The name of the method argument.
      • Argument aggregation: By specifying the same argName, multiple request parameters (each one is of basic type or repeated basic type) can be aggregated into one method argument (of any type).
        • You do not need to repeat the argName, only the first one is required.
    • in:
      • path: The method argument is sourced from a path parameter.
        • Optional: All variables (snake-case or camel-case) in pattern will automatically be bound to their corresponding method arguments (matches by name), as path parameters.
      • query: The method argument is sourced from a query parameter.
        • To receive values from a multi-valued query parameter, the method argument can be defined as a slice of basic type.
      • header: The method argument is sourced from a header parameter.
      • cookie: The method argument is sourced from a cookie parameter.
        • Not supported yet.
      • body: The method argument is sourced from the request body.
        • Deprecated: Use @kok(body) instead.
      • request: The method argument is sourced from a property of Go's http.Request.
        • This is a special case, and only one property RemoteAddr is available now.
        • Note that parameters located in request have no relationship with OAS.
    • name: The name of the corresponding request parameter.
      • Optional: Defaults to argName if not specified.
    • type: The type of the corresponding request parameter.
      • Optional: Defaults to the type of the method argument, if not specified.
      • Required for Argument aggregation for generating correct OAS documentation.
    • required: Determines whether this parameter is mandatory.
      • Optional: Defaults to false, if not specified.
      • If the parameter location is path, this property will be set to true internally, whether it's specified or not.
  • Example:
    • Simple argument:

      type Service interface {
          // @kok(op): PUT /users/{id}
          // @kok(param): name < in:header,name:X-User-Name
          // @kok(param): age < in:header,name:X-User-Age
          UpdateUser(ctx context.Context, id int, name string, age int) (err error)
      }
      
      // HTTP request:
      // $ http PUT /users/101 X-User-Name:tracey X-User-Age:1
    • Argument aggregation:

      type User struct {
          Name    string   `kok:"query.name"`
          Age     int      `kok:"query.age"`
          Hobbies []string `kok:"query.hobby"`
      }
      
      type Service interface {
          // @kok(op): POST /users
          // @kok(param): user < in:query,name:name,type:string
          // @kok(param): user < in:query,name:age,type:int
          // @kok(param): user < in:query,name:hobby,type:[]string
          CreateUser(ctx context.Context, user User) (err error)
      }
      
      // The equivalent annotations.
      type Service interface {
          // @kok(op): POST /users
          // @kok(param): user < in:query,name:name,type:string
          // @kok(param):      < in:query,name:age,type:int
          // @kok(param):      < in:query,name:hobby,type:[]string
          CreateUser(ctx context.Context, user User) (err error)
      }
      
      // HTTP request:
      // $ http POST /users?name=tracey&age=1&hobby=music&hobby=sport
Define the HTTP request body
  • Key: @kok(body)
  • Value: <field>
    • field: The name of the method argument whose value is mapped to the HTTP request body.
      • Optional: When omitted, a struct containing all the arguments, which are not located in path/query/header, will automatically be mapped to the HTTP request body.
      • The special name - can be used, to define that there is no HTTP request body. As a result, every argument, which is not located in path/query/header, will automatically be mapped to one or more query parameters.
  • Example:
    • Omitted:

      type Service interface {
          // @kok(op): POST /users
          CreateUser(ctx context.Context, name string, age int) (err error)
      }
      
      // HTTP request:
      // $ http POST /users name=tracey age=1
    • Specified as a normal argument:

      type User struct {
          Name string `json:"name"`
          Age  int    `json:"age"`
      }
      
      type Service interface {
          // @kok(op): POST /users
          // @kok(body): user
          CreateUser(ctx context.Context, user User) (err error)
      }
      
      // HTTP request:
      // $ http POST /users name=tracey age=1
    • Specified as -:

      type User struct {
          Name    string   `kok:"query.name"`
          Age     int      `kok:"query.age"`
          Hobbies []string `kok:"query.hobby"`
      }
      
      type Service interface {
          // @kok(op): POST /users
          // @kok(body): -
          CreateUser(ctx context.Context, user User) (err error)
      }
      
      // HTTP request:
      // $ http POST /users?name=tracey&age=1&hobby=music&hobby=sport
Define the success HTTP response
  • Key: @kok(success)

  • Value: statusCode:<statusCode>,body:<body>

    • statusCode: The status code of the success HTTP response.
      • Optional: Defaults to 200 if not specified.
    • body: The name of the response field whose value is mapped to the HTTP response body.
      • Optional: When omitted, a struct containing all the results (except error) will automatically be mapped to the HTTP response body.
  • Example:

    type User struct {
        Name string `json:"name"`
        Age  int    `json:"age"`
    }
    
    type Service interface {
        // @kok(op): POST /users
        // @kok(success): statusCode:201,body:user
        CreateUser(ctx context.Context) (user User, err error)
    }

Encoding and decoding

See the HTTP Codec interface.

OAS Schema

See the OAS Schema interface.

Documentation

Checkout the Godoc.

License

MIT

kok's People

Contributors

russellluo avatar

Stargazers

 avatar

Watchers

 avatar

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.