教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 手动实现 golang 自定义路由器

手动实现 golang 自定义路由器

发布时间:2022-02-15   编辑:jiaochengji.com
教程集为您提供手动实现 golang 自定义路由器等资源,欢迎您收藏本站,我们将为您提供最新的手动实现 golang 自定义路由器资源
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"/></svg><blockquote>

借鉴自 go web 一书, 作者 谢孟军,很好的一本数

</blockquote> <h4>Go 自带的路由器有几个限制:</h4> <ol><li>不支持参数设定,例如 /user/:uid 这种泛类型匹配 (url & 传参对 SEO 不友好, 对用户也不友好)</li><li>无法很好的支持 REST 模式 ):_: 我在工作中也只是用到 get post 。。。</li><li>一般网站的路由规则太多了,编写繁琐 ( 新手的我无法理解大佬的极致精神</li></ol><h5>让我们跟着大佬的思想设计一个 route register 实现 ,看招~~~</h5> <h6>先定义一个储存单元路由的信息</h6> <pre><code class="lang-go hljs"><span class="token keyword">type</span> controllerInfo <span class="token keyword">struct</span> <span class="token punctuation">{</span> regex <span class="token operator">*</span>regexp<span class="token punctuation">.</span>Regexp <span class="token comment">//保存正则路由</span> params <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">int</span><span class="token punctuation">]</span><span class="token builtin">string</span> <span class="token comment">// 路由上的单元正则匹配</span> controllerType reflect<span class="token punctuation">.</span>Type <span class="token comment">// 路由对应的控制器</span> <span class="token punctuation">}</span> </code></pre> <h6>定义一个 App 结构体 保存 app 的基本信息</h6> <pre><code class="lang-go hljs"><span class="token keyword">type</span> App <span class="token keyword">struct</span> <span class="token punctuation">{</span> Name <span class="token builtin">string</span> <span class="token punctuation">}</span> </code></pre> <h6>所有路由的集合 方便遍历等等</h6> <pre><code class="lang-go hljs"><span class="token keyword">type</span> ControllerRegistor <span class="token keyword">struct</span> <span class="token punctuation">{</span> routers <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">*</span>controllerInfo <span class="token comment">// 保存所有路由的信息</span> Application <span class="token operator">*</span>App <span class="token comment">// 应用基本信息</span> <span class="token punctuation">}</span> </code></pre> <h6>公共的 Controller 方法 所有的 控制器 都要继承这个 Controller</h6> <pre><code class="lang-go hljs"><span class="token keyword">type</span> ControllerInterface <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> </code></pre> <h6>测试控制器</h6> <pre><code class="lang-go hljs"><span class="token keyword">type</span> UserController <span class="token keyword">struct</span> <span class="token punctuation">{</span> ControllerInterface <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>u <span class="token operator">*</span>UserController<span class="token punctuation">)</span> <span class="token function">String</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"i am UserController"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>u <span class="token operator">*</span>UserController<span class="token punctuation">)</span> <span class="token function">Get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"user get request"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> </code></pre> <h6>注册路由</h6> <pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token punctuation">(</span>p <span class="token operator">*</span>ControllerRegistor<span class="token punctuation">)</span> <span class="token function">Add</span><span class="token punctuation">(</span>pattern <span class="token builtin">string</span><span class="token punctuation">,</span> c ControllerInterface<span class="token punctuation">)</span> <span class="token punctuation">{</span> parts <span class="token operator">:=</span> strings<span class="token punctuation">.</span><span class="token function">Split</span><span class="token punctuation">(</span>pattern<span class="token punctuation">,</span> <span class="token string">"/"</span><span class="token punctuation">)</span> <span class="token comment">// 根据 / 切割 url</span> j <span class="token operator">:=</span> <span class="token number">0</span> params <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">int</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token comment">// 保存匹配到的URL参数 :id 之类</span> <span class="token keyword">for</span> i<span class="token punctuation">,</span> part <span class="token operator">:=</span> <span class="token keyword">range</span> parts <span class="token punctuation">{</span> <span class="token keyword">if</span> strings<span class="token punctuation">.</span><span class="token function">HasPrefix</span><span class="token punctuation">(</span>part<span class="token punctuation">,</span> <span class="token string">":"</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 匹配到 url 上的参数了</span> expr <span class="token operator">:=</span> <span class="token string">"([^/] )"</span> <span class="token comment">// 匹配所有 的参数值</span> <span class="token comment">// 匹配用户自定义的正则</span> <span class="token keyword">if</span> index <span class="token operator">:=</span> strings<span class="token punctuation">.</span><span class="token function">Index</span><span class="token punctuation">(</span>part<span class="token punctuation">,</span> <span class="token string">"("</span><span class="token punctuation">)</span><span class="token punctuation">;</span> index <span class="token operator">!=</span> <span class="token operator">-</span><span class="token number">1</span> <span class="token punctuation">{</span> <span class="token comment">// 匹配到了用户自定义的正则</span> expr <span class="token operator">=</span> part<span class="token punctuation">[</span>index<span class="token punctuation">:</span><span class="token punctuation">]</span> part <span class="token operator">=</span> part<span class="token punctuation">[</span><span class="token punctuation">:</span>index<span class="token punctuation">]</span> <span class="token punctuation">}</span> params<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">=</span> part <span class="token comment">// 保存正则匹配到的键 比如 url 上的 :id 作为键</span> parts<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> expr <span class="token comment">// 把 url 上的 :id 参数 替换成正则表达式</span> j<span class="token operator"> </span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> pattern <span class="token operator">=</span> strings<span class="token punctuation">.</span><span class="token function">Join</span><span class="token punctuation">(</span>parts<span class="token punctuation">,</span> <span class="token string">"/"</span><span class="token punctuation">)</span> <span class="token comment">// 用 / 把切片组合起来</span> regex<span class="token punctuation">,</span> regexErr <span class="token operator">:=</span> regexp<span class="token punctuation">.</span><span class="token function">Compile</span><span class="token punctuation">(</span>pattern<span class="token punctuation">)</span> <span class="token comment">// 校验正则 返回正则实例</span> <span class="token keyword">if</span> regexErr <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> <span class="token function">panic</span><span class="token punctuation">(</span>regexErr<span class="token punctuation">)</span> <span class="token comment">// 简单写法 可以根据自己的需求定制</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> <span class="token comment">// 现在开始创建路由</span> t <span class="token operator">:=</span> reflect<span class="token punctuation">.</span><span class="token function">Indirect</span><span class="token punctuation">(</span>reflect<span class="token punctuation">.</span><span class="token function">ValueOf</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Type</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// 根据值 找到对应的 类型 也就是 对应的控制器</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"url 匹配到的 controller : "</span><span class="token punctuation">,</span> t<span class="token punctuation">)</span> route <span class="token operator">:=</span> <span class="token operator">&</span>controllerInfo<span class="token punctuation">{</span><span class="token punctuation">}</span> route<span class="token punctuation">.</span>regex <span class="token operator">=</span> regex route<span class="token punctuation">.</span>params <span class="token operator">=</span> params route<span class="token punctuation">.</span>controllerType <span class="token operator">=</span> t p<span class="token punctuation">.</span>routers <span class="token operator">=</span> <span class="token function">append</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span>routers<span class="token punctuation">,</span> route<span class="token punctuation">)</span> <span class="token punctuation">}</span> </code></pre> <h6>设置静态路由 转发静态资源</h6> <pre><code class="lang-go hljs"><span class="token keyword">var</span> StaticDir <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token builtin">string</span> <span class="token keyword">func</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> StaticDir <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>p <span class="token operator">*</span>ControllerRegistor<span class="token punctuation">)</span> <span class="token function">SetStaticPath</span><span class="token punctuation">(</span>url <span class="token builtin">string</span><span class="token punctuation">,</span> path <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> StaticDir<span class="token punctuation">[</span>url<span class="token punctuation">]</span> <span class="token operator">=</span> path <span class="token punctuation">}</span> </code></pre> <h6>转发路由到对应的方法上</h6> <pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token punctuation">(</span>p <span class="token operator">*</span>ControllerRegistor<span class="token punctuation">)</span> <span class="token function">ServeHTTP</span><span class="token punctuation">(</span>w http<span class="token punctuation">.</span>ResponseWriter<span class="token punctuation">,</span> r <span class="token operator">*</span>http<span class="token punctuation">.</span>Request<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">defer</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">if</span> err <span class="token operator">:=</span> <span class="token function">recover</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token comment">// 暴力输出 测试</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">var</span> started <span class="token builtin">bool</span> <span class="token keyword">for</span> prefix<span class="token punctuation">,</span> staticDir <span class="token operator">:=</span> <span class="token keyword">range</span> StaticDir <span class="token punctuation">{</span> <span class="token keyword">if</span> strings<span class="token punctuation">.</span><span class="token function">HasPrefix</span><span class="token punctuation">(</span>r<span class="token punctuation">.</span>URL<span class="token punctuation">.</span>Path<span class="token punctuation">,</span> prefix<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 匹配到静态路由</span> file <span class="token operator">:=</span> staticDir <span class="token operator"> </span> r<span class="token punctuation">.</span>URL<span class="token punctuation">.</span>Path<span class="token punctuation">[</span><span class="token function">len</span><span class="token punctuation">(</span>prefix<span class="token punctuation">)</span><span class="token punctuation">:</span><span class="token punctuation">]</span> <span class="token comment">// 重写静态路由</span> http<span class="token punctuation">.</span><span class="token function">ServeFile</span><span class="token punctuation">(</span>w<span class="token punctuation">,</span> r<span class="token punctuation">,</span> file<span class="token punctuation">)</span> <span class="token comment">// 调用 go 自带的静态文件处理函数 返回静态资源</span> started <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> requestPath <span class="token operator">:=</span> r<span class="token punctuation">.</span>URL<span class="token punctuation">.</span>Path <span class="token comment">// 开始比对路由</span> <span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> route <span class="token operator">:=</span> <span class="token keyword">range</span> p<span class="token punctuation">.</span>routers <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token operator">!</span>route<span class="token punctuation">.</span>regex<span class="token punctuation">.</span><span class="token function">MatchString</span><span class="token punctuation">(</span>requestPath<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">continue</span> <span class="token punctuation">}</span> <span class="token comment">// 正则匹配路由 并获取 url 上带的参数</span> matches <span class="token operator">:=</span> route<span class="token punctuation">.</span>regex<span class="token punctuation">.</span><span class="token function">FindStringSubmatch</span><span class="token punctuation">(</span>requestPath<span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token function">len</span><span class="token punctuation">(</span>matches<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token function">len</span><span class="token punctuation">(</span>requestPath<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">continue</span> <span class="token punctuation">}</span> params <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"start r.URL.RawQuery : "</span><span class="token punctuation">,</span> r<span class="token punctuation">.</span>URL<span class="token punctuation">.</span>RawQuery<span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token function">len</span><span class="token punctuation">(</span>route<span class="token punctuation">.</span>params<span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span> <span class="token punctuation">{</span> <span class="token comment">// 说明 url 上有参数</span> values <span class="token operator">:=</span> r<span class="token punctuation">.</span>URL<span class="token punctuation">.</span><span class="token function">Query</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// 获取url get 传参</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"start r.URL.Query : "</span><span class="token punctuation">,</span> values<span class="token punctuation">)</span> <span class="token keyword">for</span> i<span class="token punctuation">,</span> match <span class="token operator">:=</span> <span class="token keyword">range</span> matches<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">:</span><span class="token punctuation">]</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"matches["</span><span class="token punctuation">,</span>i<span class="token punctuation">,</span><span class="token string">"] : "</span><span class="token punctuation">,</span> route<span class="token punctuation">.</span>params<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> values<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>route<span class="token punctuation">.</span>params<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> match<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"params["</span><span class="token punctuation">,</span>i<span class="token punctuation">,</span><span class="token string">"] added , r.URL.Query : "</span><span class="token punctuation">,</span> values<span class="token punctuation">)</span> params<span class="token punctuation">[</span>route<span class="token punctuation">.</span>params<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">=</span> match <span class="token punctuation">}</span> r<span class="token punctuation">.</span>URL<span class="token punctuation">.</span>RawQuery <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">Values</span><span class="token punctuation">(</span>values<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Encode</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator"> </span> <span class="token string">"&"</span> <span class="token operator"> </span> r<span class="token punctuation">.</span>URL<span class="token punctuation">.</span>RawQuery <span class="token comment">// 添加参数到 原始url 上</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"changed r.URL.RawQuery : "</span><span class="token punctuation">,</span> r<span class="token punctuation">.</span>URL<span class="token punctuation">.</span>RawQuery<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">// 利用反射机制 获取 绑定的 控制器</span> vc <span class="token operator">:=</span> reflect<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span>route<span class="token punctuation">.</span>controllerType<span class="token punctuation">)</span> method <span class="token operator">:=</span> vc<span class="token punctuation">.</span><span class="token function">MethodByName</span><span class="token punctuation">(</span><span class="token string">"Miss"</span><span class="token punctuation">)</span> <span class="token comment">//init := vc.MethodByName("init")</span> <span class="token keyword">if</span> r<span class="token punctuation">.</span>Method <span class="token operator">==</span> <span class="token string">"GET"</span> <span class="token punctuation">{</span> method <span class="token operator">=</span> vc<span class="token punctuation">.</span><span class="token function">MethodByName</span><span class="token punctuation">(</span><span class="token string">"Get"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> r<span class="token punctuation">.</span>Method <span class="token operator">==</span> <span class="token string">"POST"</span> <span class="token punctuation">{</span> method <span class="token operator">=</span> vc<span class="token punctuation">.</span><span class="token function">MethodByName</span><span class="token punctuation">(</span><span class="token string">"Post"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// 其它 RESTFUL 风格就不写了 如果有需要请读者 自己 else if 下去</span> <span class="token punctuation">}</span> in <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span>reflect<span class="token punctuation">.</span>Value<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> method<span class="token punctuation">.</span><span class="token function">Call</span><span class="token punctuation">(</span>in<span class="token punctuation">)</span> started <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token keyword">break</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> started <span class="token operator">==</span> <span class="token boolean">false</span> <span class="token punctuation">{</span> http<span class="token punctuation">.</span><span class="token function">NotFound</span><span class="token punctuation">(</span>w<span class="token punctuation">,</span> r<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <h6>跑起来</h6> <pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> p <span class="token operator">:=</span> <span class="token operator">&</span>ControllerRegistor<span class="token punctuation">{</span><span class="token punctuation">}</span> p<span class="token punctuation">.</span><span class="token function">SetStaticPath</span><span class="token punctuation">(</span><span class="token string">"/img/"</span><span class="token punctuation">,</span> <span class="token string">"/static/img/"</span><span class="token punctuation">)</span> p<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token string">"/user/:uid([0-9] )"</span><span class="token punctuation">,</span> <span class="token operator">&</span>UserController<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"regex : "</span><span class="token punctuation">,</span>p<span class="token punctuation">.</span>routers<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>regex<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"params : "</span><span class="token punctuation">,</span>p<span class="token punctuation">.</span>routers<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>params<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"start listen"</span><span class="token punctuation">)</span> err <span class="token operator">:=</span> http<span class="token punctuation">.</span><span class="token function">ListenAndServe</span><span class="token punctuation">(</span><span class="token string">"127.0.0.1:9999"</span><span class="token punctuation">,</span> p<span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"listen failed : "</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre>

上一篇 go websocket 基本源码解读

到此这篇关于“手动实现 golang 自定义路由器”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
golang日志服务器_深扒GO日志 | (一)从Go语言的日志包说起
Lumen 5.2 HTTP 路由入门教程
Go语言Web基础--Go的http包详解
golang版的traceroute实现
Golang基础第五篇——golang的gRPC
数据结构和算法(Golang实现)(10)基础知识-算法复杂度主方法
为什么要学 Go
路由器上网经常掉线怎么办 上网掉线解决方法
PHP路由库FastRoute的使用教程
Go语言微服务开发框架实践-go chassis(中篇)

[关闭]
~ ~