这份文档包含使用protoapi所需条件, 以及如何使用protoapi
- 本项目基于
go的实现 - 目的:自动生成前后端API的基础代码,节省开发时间
- 前端生成TypeScript的代码, 客戶端
 - 后端目前支持生成java (spring) 和go (echo)的代码
 
 - 当前版本: 0.1.1
 
安装go 1.10以上版本:
- go安装
 - 需要确保$GOPATH设置正确
 
- 下载项目代码:
 
go get github.com/yoozoo/protoapi
- 使用
protoapi自动初始化protoc: 
protoapi init
- 
protoapi gen --lang=[language] [output directory] [proto file] - 
生成前端TypeScript代码:
protoapi gen --lang=ts [output_folder] [proto file path] - 
生成前端PHP代码:
protoapi gen --lang=php [output_folder] [proto file path] - 
生成后端Spring代码:
protoapi gen --lang=spring [output_folder] [proto file path] - 
生成后端echo代码:
protoapi gen --lang=echo [output_folder] [proto file path] - 
生成后端markdown代码:
protoapi gen --lang=markdown [output_folder] [proto file path] 
例如:
- 
生成前端TypeScript代码:
protoapi gen --lang=ts . ./test/proto/todolist.proto - 
生成后端Spring代码:
protoapi gen --lang=spring . ./test/proto/todolist.proto - 
其他相关command请参考这里
 
- generator
- data 包含数据结构
- tpl/tpl.go
 - data.go 定义共享的数据结构
 
 - output 包含代码生成的具体逻辑
- echo_xx.go 支持生成echo的代码
 - spring_xx.go 支持生成spring的代码
 - vue_ts.go 支持生成vue(使用ts)的代码
 - php.go 支持生成php的代码
 - markdown.go 支持生成markdown的代码
 
 - template 包含所有模板文件
- ts xx.gots TS的模板 xx.govue Vue的模板
 - echo_xx.gogo go的模板(对应echo)
 - spring_xx.gojava java的模板(对应spring)
 - php.gophp php的模板
 - markdown.gomd markdown的模板
 
 - generator.go 包含一些共享的代码生成函数逻辑
 
 - data 包含数据结构
 - test 包含所有测试代码生成的proto文件
 
- 先完成编译
go build - 将编译出来的可执行文件设置到
PROTOAPI_EXE环境变量 - 再执行
go test 
- 在generator/template文件夹里添加新的template:
 
- 具体语法可参考这里
 - 现有例子可参考generator/template里已有的template
 - 新添加template文件根据生成文件命名后缀, 如生成ts文件则命名为:xxx.gots, 生成java文件则叫xxx.gojava等
 
- 在generator/output文件夹里添加新的xxx.go文件或改动现有文件的逻辑
 
- 后端代码可参考generator/output/spring.go
 - 前端代码可参考generator/output/ts.go
 - 例如,如果想要多生成一个ts文件:
- 添加新的模板: generator/template/ts/example.gots
 - 在generator/output/ts.go里面
 
 
        type tsGen struct {
            // 1. 添加数据
            ...
            exampleFile string
            ...
            exampleTpl       *template.Template
        }
        ...
        /**
        * Get TEMPLATE
        */
        func (g *tsGen) loadTpl() {
            ...
            // 2. 添加输入的模板
            g.exampleTpl = g.getTpl("/generator/template/ts/example.gots")
        }
        /**
        * init filename with path
        */
        func (g *tsGen) initFiles(packageName string, service *data.ServiceData) {
        	g.axiosFile = genFileName(packageName, service.Name)
			...
			// 3. 添加生成的文件名
			// 新生成文件会命名为: example.ts, 并根据packageName指定生成于哪个文件夹
			// 例如: packageName = yoozoo.protoconf.ts的话, 文件会生成与 $output_dir/yoozoo/protoconf/ts
			// packageName 定义于proto文件内: “package yoozoo.protoconf.ts;”
            g.exampleFile=genFileName(packageName, "example"),
            
		}
 		/**
        * init generate file
        */
        func (g *tsGen) Gen(applicationName string, packageName string, svrs []*data.ServiceData, messages []*data.MessageData, enums []*data.EnumData, options data.OptionMap) (map[string]string, error) {
            ...
            /**
            * combine data with template
            */
            // 4. 最后输出生成的文件
            ...
            result[g.exampleFile] = g.genContent(g.exampleTpl, dataMap)
            ...
        }- 参考【建立执行文件/插件】 和 【如何使用插件】测试新加的模板
- 可测试现有的proto样本文件:
protoapi/test/hello.proto - 或自定义proto文件测试
 
 - 可测试现有的proto样本文件:
 
syntax = "proto3"; // 使用proto3的语法
option java_package = "com.yoozoo.spring"; //生成的java文件在[output_folder]/com/yoozoo/spring文件夹内
package com.yoozoo.ts; //生成的ts文件在[output_folder]/com/yoozoo/ts文件夹内
import "test/messages.proto"; //引用其他proto文件
// 定义service
service HelloService {
    rpc SayHello (HelloRequest) returns (HelloResponse);
}
- 所有API生成默认使用HTTP POST
 - 特效场景下可以使用GET,但不鼓励, 因为query string无法很好的对复杂请求对象做序列化
 
[ ] 修改Common Struct的识别方式,目前只有在提供Service文件时才能判断