• GO --微服务框架(一) goa


    当项目逐渐变大之后,服务增多,开发人员增加,单纯的使用go来写服务会遇到风格不统一,开发效率上的问题。
    之前研究go的微服务架构go-kit最让人头疼的就是定义服务之后,还要写很多重复的框架代码,一直再想如何使用IDL描述服务,然后自动生成框架代码。
    直到遇到老这货 goa,另外一个go的微服务框架。具体介绍看这篇,还有官网
     
    这货实现了框架的代码自动生成(自动生成的代码可以热更新,因为生成代码和自己写的代码是分开的),而且理念也比较时髦,基于API设计,利用插件来扩展业务逻辑。
     
    于是想想要赶紧学习玩一下。
     
    假定你已经装了golang的环境。
    所以,开始下载。
    go get github.com/goadesign/goa
    go get github.com/goadesign/goa/goagen
    
    go install github.com/goadesign/goa
    go install github.com/goadesign/goa/goagen

     安装好之后,就可以用help命令来查看使用方式了。

    复制代码
    qingping.zhang@qpzhangmac ~/dev goagen --help
    The goagen tool generates artifacts from a goa service design package.
    
    Each command supported by the tool produces a specific type of artifacts. For example
    the "app" command generates the code that supports the service controllers.
    
    The "bootstrap" command runs the "app", "main", "client" and "swagger" commands generating the
    controllers supporting code and main skeleton code (if not already present) as well as a client
    package and tool and the Swagger specification for the API.
    
    Usage:
      goagen [command]
    
    Available Commands:
      app         Generate application code
      main        Generate application scaffolding
      client      Generate client package and tool
      swagger     Generate Swagger
      js          Generate JavaScript client
      schema      Generate JSON Schema
      gen         Run third-party generator
      bootstrap   Equivalent to running the "app", "main", "client" and "swagger" commands.
    
    Flags:
          --debug           enable debug mode, does not cleanup temporary files.
      -d, --design string   design package import path
      -o, --out string      output directory (default "/Users/qingpingzhang/dev")
    
    Use "goagen [command] --help" for more information about a command.
    复制代码

    然后需要yaml包的支持,所以需要提前安装:

    go get gopkg.in/yaml.v2

    必须要在GOPATH的src的目录下,新建一个目录(例如:goa.demo),然后在它下面新建一个design的子目录。

    子design目录下,新建文件design.go

    复制代码
    //design.go
    
    package design                                     // The convention consists of naming the design
                                                       // package "design"
    import (
            . "github.com/goadesign/goa/design"        // Use . imports to enable the DSL
            . "github.com/goadesign/goa/design/apidsl"
    )
    
    var _ = API("cellar", func() {                     // API defines the microservice endpoint and
            Title("The virtual wine cellar")           // other global properties. There should be one
            Description("A simple goa service")        // and exactly one API definition appearing in
            Scheme("http")                             // the design.
            Host("localhost:8080")
    })
    
    var _ = Resource("bottle", func() {                // Resources group related API endpoints
            BasePath("/bottles")                       // together. They map to REST resources for REST
            DefaultMedia(BottleMedia)                  // services.
    
            Action("show", func() {                    // Actions define a single API endpoint together
                    Description("Get bottle by id")    // with its path, parameters (both path
                    Routing(GET("/:bottleID"))         // parameters and querystring values) and payload
                    Params(func() {                    // (shape of the request body).
                            Param("bottleID", Integer, "Bottle ID")
                    })
                    Response(OK)                       // Responses define the shape and status code
                    Response(NotFound)                 // of HTTP responses.
            })
    })
    
    // BottleMedia defines the media type used to render bottles.
    var BottleMedia = MediaType("application/vnd.goa.example.bottle+json", func() {
            Description("A bottle of wine")
            Attributes(func() {                         // Attributes define the media type shape.
                    Attribute("id", Integer, "Unique bottle ID")
                    Attribute("href", String, "API href for making requests on the bottle")
                    Attribute("name", String, "Name of wine")
                    Required("id", "href", "name")
            })
            View("default", func() {                    // View defines a rendering of the media type.
                    Attribute("id")                     // Media types may have multiple views and must
                    Attribute("href")                   // have a "default" view.
                    Attribute("name")
            })
    })
    复制代码

    然后使用命令,来自动生成框架代码(这里需要注意,如果不加-o选项指定输出目录 , 这些代码是会生成到当前目录下的哦):

    复制代码
     qingping.zhang@qpzhangmac ~/gocode/src/goa.demo/  goagen bootstrap -d goa.demo/design
    app
    app/contexts.go
    app/controllers.go
    app/hrefs.go
    app/media_types.go
    app/user_types.go
    app/test
    app/test/bottle.go
    main.go
    bottle.go
    client
    client/cellar-cli
    client/cellar-cli/main.go
    client/cellar-cli/commands.go
    client/client.go
    client/bottle.go
    client/datatypes.go
    swagger
    swagger/swagger.json
    swagger/swagger.yaml
    复制代码

    尼玛,咔咔咔。。。生成好多。

    框架会默认生成结构的返回值,所以,这里我们暂时不做任何修改,因为还没有介绍生成的代码目录。

    所以我们直接编译,运行看看。

    复制代码
     qingping.zhang@qpzhangmac ~/gocode/src/goa.demo go build
     qingping.zhang@qpzhangmac ~/gocode/src/goa.demo ./goa.demo
    2016/05/26 15:45:09 [INFO] mount ctrl=Bottle action=Show route=GET /bottles/:bottleID
    2016/05/26 15:45:09 [INFO] listen transport=http addr=:8080
    
    2016/05/26 15:46:21 [INFO] started req_id=qAWO65SPCG-1 GET=/bottles/1 from=127.0.0.1 ctrl=BottleController action=Show
    2016/05/26 15:46:21 [INFO] params req_id=qAWO65SPCG-1 bottleID=1
    复制代码

    然后再另外一个窗口发起请求,结果如下:

    复制代码
     qingping.zhang@qpzhangmac  ~  curl -i localhost:8080/bottles/1
    HTTP/1.1 200 OK
    Content-Type: application/vnd.goa.example.bottle
    Date: Thu, 26 May 2016 07:07:40 GMT
    Content-Length: 29
    
    {"href":"","id":0,"name":""}
    复制代码

    到这里,整个安装使用就OK来。

    后面再分析,自动生成的代码目录以及如何增加自己的业务逻辑代码。

    ========================

    update 2016.7.17

    如果重复执行代码生成命令时: goagen bootstrap -d goa.demo/design

    main.go 和 bottle.go 是不会重新生成的,这就保证业务逻辑代码不会被覆盖。

    但若是后面新增的Action,要自己在业务逻辑代码里头,手动添加函数体代码。

    ========================

  • 相关阅读:
    php 全局变量 2
    PHP 全局变量 1
    巧用sublime
    ini_get和ini_set
    sublime安装sftp
    常用数组函数
    二维数组去重
    判断常量
    system(),exec() ,passthru()
    【收集】Python 微优化
  • 原文地址:https://www.cnblogs.com/mafeng/p/6732964.html
Copyright © 2020-2023  润新知