golang api service, where to handle database requests?

polaris · · 204 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hi,</p> <p>i am currently developing a set of go microservices. Each of them should be an api and be deployed on our app engine server. Right now i am asking myself where should i make requests in the database? </p> <p>Following the DRY principles i know from ruby on rails it should be in the model class. Lets say i want to provide a microservice for users. Imagine i got an endpoint app.com/api/user-service/v1/:id which will be handled by the GetUser handler in the user controller. Should i know request the user from the database in the controller function or rather than call a method for that in the user model? Also if someone has a Link to a well designed go api service it would be great to post it here.</p> <p>best, rap3</p> <hr/>**评论:**<br/><br/>scottjbarr: <pre><p>I like to structure it like this... Server -&gt; Handlers -&gt; Services -&gt; Repository -&gt; DB.</p> <p>You have the Server and Handlers.</p> <p>A Handler only speaks to Services. The handler takes the data from the request, and calls a service with the data. The Handlers deal with all HTTP concerns. If the Service returns an error, the Handler communicates this to the caller.</p> <p>A Service could communicate with 1 or more Repositories. A Service has no concept of HTTP. </p> <p>A Respository handles communication with a single data source. The data source could be a single table in a DB, a queue, or maybe SQS buckets. It depends on what your data is. A Repository returns models, but not actual DB rows.</p> <p>The separation of layers means testing stays fairly simple.</p> <p>Unfortunately I don&#39;t have an example I can share.</p></pre>MEAT_FIST: <pre><p>I am using the exact same approach and am quite happy with it.</p> <p>Bonus points if your Services and Repository are all interfaces that can be mocked.</p></pre>scottjbarr: <pre><p>Absolutely. Interfaces make the whole thing simple to mock out for testing and local development :)</p></pre>boxtown: <pre><p>For simple web applications, I&#39;ve been using the following pattern:</p> <p>Define a data layer interface ala <a href="https://github.com/boxtown/meirl/blob/master/data/stores.go#L76" rel="nofollow">example</a></p> <p>The interface can then be implemented specifically for a data source like PostgreSQL, MongoDB, or a mock store for testing.</p> <p>I then define an API/Handler layer through API objects that take in the data layer interface ala <a href="https://github.com/boxtown/meirl/blob/master/api/user_api.go#L21" rel="nofollow">example</a>.</p> <p>The API objects then define handler functions that interact with the data layer interface and respond appropriately</p></pre>earthboundkid: <pre><p>See this blog series: <a href="https://medium.com/wtf-dial/wtf-dial-domain-model-9655cd523182" rel="nofollow">https://medium.com/wtf-dial/wtf-dial-domain-model-9655cd523182</a></p></pre>alioygur: <pre><p><a href="https://github.com/alioygur/gocart" rel="nofollow">https://github.com/alioygur/gocart</a></p> <p>may it help you</p></pre>jns111: <pre><p>I usually go this way. 1. Create a User Store Interface (CRUD) =&gt; UserStore 2. Implement the Methods =&gt; UserStoreImpl 3. Create a UserHandler (handling the routes) On Service start I use facebook inject to inject UserStoreImpl into the Object Graph. In UserHandler I will require UserStore interface and use it&#39;s methods, which gets satisfied by UserStoreImpl. You can now write a test and inject a mock object, implementing the UserStore interface into your handler. This way you can test your handlers in isolation. On Top of that, if you decide to use UserStore everywhere else just require the injected Object from the object Graph and you are done. DRY and testable.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

204 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传