How to implement the presenter in Golang according to the Clean Architecture?

Multi tool use
Multi tool use


How to implement the presenter in Golang according to the Clean Architecture?



Proper software architecture is key to create a project that is maintainable. What proper means is 100% subjective,
but lately I like and try to follow Clean Architecture by Robert C. Martin (aka Uncle Bob).



Although I really like the theory, it lacks some sort of practical implementation guide for common technical challenges developers may face.
One of the things I've been struggling with for example is properly implementing the presenter layer.



The presenter is responsible for accepting the "response" from my use case and formatting it in a way
that it can be "presented" to my output device (regardless if it is a web or a CLI application).



There are multiple approaches for this problem, but they usually fall under one of these categories:



Option 1 is more or less the same as what Clean Architecture/Uncle Bob says (in the book and in various posts, see later), Option 2 is rather an alternative approach which works.



Sounds cool, but let's see how we can implement them in Go.



Here is my first version. For simplicity, our output goes to the web now.



Also, please excuse my brevity.


package my_domain

import "http"

type useCase struct {
presenter presenter
}

func (uc *useCase) doSomething(arg string) {
uc.presenter("success")
}

type presenter interface {
present(respone interface{})
}

type controller struct {
useCase useCase
}

func (c *controller) Action(rw http.ResponseWriter, req *http.Request) {
c.useCase("argument")
}



Basically it does exactly as described above and in Clean Architecture: There is a controller which calls a use case (through a boundary, which is not present here). The use case does something and calls the presenter (which is not implemented, but it's exactly the question).



Our next step could be implementing the presenter....but given how output works in Go HTTP handlers there is a nice problem to solve. Namely: request scope.



Every request has it's own response writer (passed to the http handler) where the response should be written. There is no global request scope that can be accessed by the presenter, it needs the response writer. So if I want to follow option 1 (use case calling the presenter), I have to pass it somehow to the presenter which becomes request scoped this way, while the rest of the application is completely stateless and not request scoped, they are instantiated once.



That also means that I either pass the response writer itself to the use case and the presenter (and I would rather not do that) or create a new presenter for each request.



Where can I do that:



This bring in another problem: if the presenter is request scoped, is the use case too?



If I want to inject the presenter into the use case struct, then yes it is and the use case has to be created in the controller as well.



Alternatively I can make the presenter a parameter of the use case (noone said a dependency must be injected at "construction time"). But that would still somewhat couple the presenter to the controller.



There are other, unanswered issues (like where should I send HTTP headers for example), but those are less Go specific.



This is a theoretical question as I'm not yet sure that I want to use this pattern, but I've spent quite an amount of time thinking about this problem without finding the perfect one so far.



Based on the articles and questions I've read about the topic: others haven't either.




1 Answer
1



I can tell you about my experience according to Clean Architecture. I spent time on that issue, reading articles and testing code. So I'd like to suggest you the following post and the source code attached, it helped me a lot:



It's a really good starting point, I'm designing my software in that way developing restful web app up to the presentation to the user passing through jQuery and Bootstrap. I can claim that now my software is really diveded into indipendent layers. Also it helped me to undestand the power of te golang interfaces and finally make simple testing each part of software.
Hope this help you too.





I've already read this article and I think this is great, but it also solves the problem by simply returning the response and does not call the presenter from the use case. I would rather see a solution for that. But thanks anyway!
– mark.sagikazar
Jul 1 at 13:56






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

wJM9lAuQn qLq U,0GF,SvV3ZFp,m441Rc28dI4WeTi82dL7So62TlgcmW7hZdq7xC5nd B GoN6RpQvTW4BR5sJ514lDEMy,zn
9krDAplej5f6Gpxufp N

Popular posts from this blog

Rothschild family

Cinema of Italy