<p>Hi,</p>
<p>I'm developing some services in go and need to provide API documentation.</p>
<p>I've written documentation in swagger which I believe is complete... but its probably not and is likely to go out of date...</p>
<p>I have a full suite of integration gets that tests my service / behaviors and makes sure its doing what its meant to do.</p>
<p>What seems natural is in my integration tests to validate my requests / reponses and warn / fail, but I cant see anything that does that.</p>
<p>It seems most of the swagger stuff is about generating server code which I dont want to do.</p>
<p>Anyone know of anything that could be useful? This <a href="https://github.com/gchaincl/swagger-proxy" rel="nofollow">Go proxy</a> comes close but with the vendor folder I get type conflicts if I try and use it and it doesnt really give me any granularity, although, just a log at the integration tests would be a big step forward to syncing up my API doc and what actually goes on and I can script / hack around with that, but not so nice.</p>
<p>Any help would be great thanks!</p>
<hr/>**评论:**<br/><br/>kemitche: <pre><p>I don't know of anything like that, though that proxy looks like it's what you want. You may just need to fiddle with it a bit to get it doing what you need?</p>
<blockquote>
<p>It seems most of the swagger stuff is about generating server code which I dont want to do.</p>
</blockquote>
<p>Can you share why not? At my job I switched our go API server workflow to one that has us writing the spec first, then generating code from the spec and wiring it through. It's perfect because it <em>ensures that the documentation is always up-to-date</em> and accurate. And we never end up with new undocumented endpoints/parameters/responses because the "easy path" is just to write/update the spec and regenerate code.</p>
<p>Switching was admittedly a bit of work, but overall it's definitely saved us more time than anything, and my client devs are glad to always have up-to-date and correct documentation.</p></pre>the_guitar_licked_me: <pre><p>Yeah thinking fiddling with the proxy stuff may be the route.</p>
<p>I've generally found most auto generated code is fairly hideous and painful to debug when something goes wrong. </p>
<p>Then, I found when you have your API, whether or not it works is down to your wiring so you still need some more behavioural based tests to actually test the API is meant to be doing what its doing, I.e. the api could match your schema but can be doing odd things. Generally found it more pain than its worth.</p>
<p>Do you auto generate in go? I'd be intruiged to hear what libraries you use, as much as I usually dislike I am always open to new / different approaches.</p></pre>kemitche: <pre><p>Yeah, I auto-generate in go. I use <a href="https://github.com/go-swagger/go-swagger/" rel="nofollow">go-swagger</a>. It has a couple flags on generation where it can build your "whole stack" (all the way down to the <code>func main()</code>) or you can just build the routes and wire them up. I do the latter.</p>
<p>The tool has been spot on. I wire up the handler, and it passes in the parameters I defined, and then I pack my response into generated objects representing either success cases or errors. There's no business logic in my handlers; I take the params and call into a native go func, then take the result of that func (or error), wrap it in the appropriate response object and return that. So that layer is simple enough that I don't need to test it exhaustively; I can focus on unit/integration testing the pure-go functions (that know nothing about HTTP).</p></pre>kemitche: <pre><p>Follow up: As an example, here's what my "glue" code for one of my endpoints looks like:</p>
<pre><code>func UserHandler(params operations.GetV1MeParams, authedUser interface{}) middleware.Responder {
if authedUser == nil {
return operations.NewGetV1UserUnauthorized().WithPayload(ErrSignInRequired)
}
user, err := DB.LoadUser(params.UserID)
if err != nil {
// Intentional panic - triggering 500s on errors connecting to DB
// Could also have defined a response in swagger and returned that.
panic(err)
}
return operations.NewGetV1UserOK().WithPayload(&models.User{
ID: user.ID,
Name: user.Name,
/* etc. */
})
}
</code></pre>
<p>The <code>params</code>, <code>models</code> and <code>operations</code> packages are generated. The endpoint parameters are validated based on how you define them in the spec, and the router will error out early with an appropriate response if validation fails. Nothing I do here is stuff I could've avoided writing anyway (I use separate structs for the API from the internal structs as a way to ensure that any data leaving the system has been whitelisted so new fields on internal structs don't leak info through the API).</p>
<p>Testing of business logic is done on the <code>DB.LoadUser</code> function, so it's isolated from any tweaks that get made to the swagger spec. (Obviously if user IDs change from ints to strings or whatever, coordination needs to happen, but that's true regardless of approach).</p></pre>the_guitar_licked_me: <pre><p>Thats a great help thanks and looks interesting. We're writing a few new services, so may try to get peoples buy in to try something like this on one and see how it goes.</p>
<p>Thanks!</p></pre>hackop: <pre><p>Maybe something like this is what you're asking for?
<a href="https://github.com/apiaryio/dredd" rel="nofollow">https://github.com/apiaryio/dredd</a></p>
<p>Apiary (now owned by Oracle.....ugh) had some pretty cool stuff. Dredd, above, is by them and open source.</p>
<p>You may also want to look at <a href="https://restlet.com/" rel="nofollow">https://restlet.com/</a>. Not sure if that matches what you want but they have a nice suite of API-related tools.</p>
<p>Edit: From a design philosophy, it seems the idea is the Swagger/OpenAPI Spec doc is the source of truth and the code is written to meet the spec. People who generate the spec docs from the code are kind of doing it backwards and eliminating the ability to test properly. So, if you think your swagger doc "is likely to go out of date", you may be approaching this in not the best way. Keep the spec up-to-date first, and then code around it.</p></pre>the_guitar_licked_me: <pre><p>Thanks, will take a look at those links.</p>
<p>Yeah kinda what I said below, generally found the autogen code annoying to work with and kinda the reverse problem, api doing odd things conforming to the schema is "OK". But yeah more tests or bed like tests couple would help.</p>
<p>Ultimately I kinda feel the swagger isn't a spec, details messages but lacks big context.</p>
<p>Obviously fairly new to this sort of stuff,so trying g to keep an open mind :p</p></pre>gchain: <pre><p><a href="https://github.com/gchaincl/swagger-proxy" rel="nofollow">https://github.com/gchaincl/swagger-proxy</a> is still a work in progress but it does the job</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传