用 TypeScript 写了一个 Mock Protobuf 的 CLI 工具 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
jasonkayzk
V2EX    分享创造

用 TypeScript 写了一个 Mock Protobuf 的 CLI 工具

  •  1
     
  •   jasonkayzk
    JasonkayZK 2022-10-09 10:43:38 +08:00 2089 次点击
    这是一个创建于 1097 天前的主题,其中的信息可能已经有所发展或是发生改变。

    用 TypeScript 写了一个 Mock Protobuf 的工具

    使用

    使用 npm 安装:

    npm i mock-pb-cli@latest -g 

    可以使用下面命令查看帮助:

    $ mock-pb -h Usage: mock-protobuf [options] [command] A tool to mock protobuf Options: -v, --version output the version number -h, --help display help for command Commands: s|serve [options] Create a mock server for the given protobuf g|generate [options] Generate mock data for the given protobuf help [command] display help for command 

    有两个子命令:

    • mock-pb gmock-pb generate:Mock JSON 数据;
    • mock-pb s or mock-pb serve:Mock 服务;

    Mock JSON 数据

    Generate 子命令主要是用来生成 Mock 的 JSON 数据;

    例如:

    $ mock-pb g 

    上面的命令会获取当前工作目录下所有的 Proto 文件,并且将 Mock 的数据输出到终端;

    例如:

    Mocked demo.BasicResponse: { "status": 902735693509892, "message": "Vmucue hqxllqx oiloapzwp.", "resp": {} } Mocked demo.DemoRequest: { "data": "Kqr gxxq." } Mocked demo.DemoResponse: { "resp": { "status": -6061376970430480, "message": "Xpjzjyxrcq eqkmytjo.", "resp": {} }, "resp_data": "Ryogd tswayqjsf." } 

    默认情况下的 Protobuf 文件搜索路线为 .,你也可以使用 -d 来指定路径!

    例如:

    $ mock-pb g -d ../test/proto 

    同时,默认情况下 Mock 数据会打印到终端,你也可以使用 -o 来指定将 Mock 的数据输出到指定的目录!

    例如:

    $ mock-pb g -o ./mock-pb-output 

    此时,mock-pb-output 目录下的结果为:

    $ tree . ├── demo │ ├── BasicResponse.json │ ├── DemoRequest.json │ └── DemoResponse.json ├── google.api │ ├── CustomHttpPattern.json │ ├── HttpBody.json │ ├── Http.json │ └── HttpRule.json └── google.protobuf ├── Any.json ├── Api.json ...... ├── SourceContext.json ├── Type.json └── UninterpretedOption.json 

    输出中的目录结构是根据 Proto 文件中的 package 来产生的!


    Mock 服务

    基本用法

    除了产生 Mock 的数据,也可以直接 Mock 服务接口;

    下面的命令会读取当前工作目录下的 Proto 文件,并 Mock 在 Service 中定义了的 Method:

    $ mock-pb s 

    输出如下:

    Handling routePath: /Demo Handling routePath: /demo/DemoServiceAnotherDemo restify listening at http://[::]:3333 

    在服务端启动时,会打印出每个接口的请求路径;

    默认情况下的服务端口号为:3333,你可以使用 -p 来自定义端口;

    例如:

    • mock-pb s -p 13333

    如果你在你的 Method 中通过 google.api.http 定义了请求路径,那么在 Mock 服务的时候会使用这个路径;

    例如:

    service DemoService { rpc Demo(DemoRequest) returns (DemoResponse) { option (google.api.http) = { post: "/Demo" body: "*" }; } } 

    如果没有指定请求路径,那么请求路径为:/{ProtobufPackageName}/{ProtobufMethodName}

    例如:

    syntax = "proto3"; package demo; service DemoService { rpc AnotherDemo(AnotherDemoRequest) returns (AnotherDemoResponse) {} } 

    当服务启动后的请求路径为:

    $ curl localhost:3333/demo/DemoServiceAnotherDemo {"resp":{"status":-843357854531144,"message":"Vzby.","resp":{}},"resp_data":"Kvia gfkcggmuo."} 

    自定义返回值

    有时候你可能并不想 Mock 一些像下面这些无意义的数据:

    {"resp":{"status":-843357854531144,"message":"Vzby.","resp":{}},"resp_data":"Kvia gfkcggmuo."} 

    而是想要自定义一些有用的返回值,比如:

    {"resp":{"status":200,"message":"ok"},"resp_data":{"Message":"This is a demo message"}} 

    此时可以创建配置文件,例如:

    mock-protobuf.config.json

    { "ResponseValue": [ { "MethodName": "demo.Demo", "Data": { "Hello": "world" } }, { "MethodName": "demo.AnotherDemo", "Data": { "resp": { "status": 200, "message": "ok" }, "resp_data": { "Message": "This is a demo message" } } } ] } 

    其中 MethodName 是 Proto 文件中 Method 的全名:package.method

    同时,你也可以通过 -c 请求来指定你的配置文件路径,例如: -c ./mock-protobuf.config.json

    下面是一个完整的命令行例子:

    $ npm run dev -- s -i demo -c ./mock-protobuf.config-demo.json 

    使用自定义返回值后的响应如下:

    $ curl localhost:3333/Demo {"Hello":"world"} $ curl localhost:3333/demo/DemoServiceAnotherDemo {"resp":{"status":200,"message":"ok"},"resp_data":{"Message":"This is a demo message"}} 

    过滤条件

    有的时候我们并不想 Mock 所有的 Proto 定义,此时可以使用 Filter 过滤条件;

    有两种方式进行过滤:

    • 包含 Includes: -i <string>--include;
    • 不包含 Excludes: -e <string>--exclude;

    上面的 <string> 被定义为一个 JS 中的正则表达式 RegExp,所以可以使用类似于正则表达式的方式对 Proto 定义进行匹配:packageName.serviceName.methodName

    多个条件使用 , 分隔!


    Include 过滤条件

    当使用 Include 过滤条件,只有匹配的 Proto 定义才会被 Mock ;

    例如:

    $ mock-pb g -i demo Mocked demo.BasicResponse: { "status": -978663427598816, "message": "Iymo zomttydmb.", "resp": {} } Mocked demo.DemoRequest: { "data": "Mdnbfxbvoq khrbwyu sxmkev jss." } Mocked demo.DemoResponse: { "resp": { "status": 6207610394471496, "message": "Dkwse mmhmuhhunb.", "resp": {} }, "resp_data": "Fqwkd noiefpr ntjbcfydl." } Mocked demo.AnotherDemoRequest: { "name": "Puvujqy kyxl hshuysly.", "age": 175838119803604 } Mocked demo.AnotherDemoResponse: { "resp": { "status": -7659482750118844, "message": "Fygec kyzysqqga svimupy nbfrjt.", "resp": {} }, "resp_data": "Mpgjtjsbr qfspgkb xmpji." } 

    上面的命令只会为 demo.* 产生 Mock 数据(即:package 为 demo 的那些定义)!

    另外一个例子:

    $ mock-pb g -i demo.DemoRequest.* Mocked demo.DemoRequest: { "data": "Ewqzspj hjkfvvc froqdhkwe fkqsdg dytidwli." } 

    此时只会 Mock:demo.DemoRequest 这一个 Message !


    Exclude 过滤条件

    相反的,-e 产生将会排除那些匹配的 Message ;

    例如:

    $ mock-pb g -e demo.*,google.protobuf.* -o mock-pb-gen $ tree . └── google.api ├── CustomHttpPattern.json ├── HttpBody.json ├── Http.json └── HttpRule.json 

    上面的命令将不会 Mock demo.*google.protobuf.* 下的 Message !

    <font color="#f00">注意:当你同时使用 include and exclude 两个过滤器,exclude 会永远首先生效!</font>

    例如:

    code class="language-bash">$ mock-pb g -i demo -e demo 

    什么都不会输出,因为所有的内容都被过滤掉了!


    关于整个开发的过程以及思路,我也放到了我的博客:

    希望对 TypeScript 初学者,以及想使用 TypeScript 编写 CLI 小工具的小伙伴们有帮助!

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2836 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 14:08 PVG 22:08 LAX 07:08 JFK 10:08
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86