implementation of GWI go challenge#68
Conversation
initial commit, connection with database, database models, endpoints
Refactoring
add swagger, fix some endpoints, add Readme
add more unit tests, update readme
update readme, remove store.go
NikosMas
left a comment
There was a problem hiding this comment.
Hi @steliosant 👋
Thanks again for the time and effort you put into this project — I really enjoyed reviewing it.
Happy to see:
- Great documentation overall (Swagger), plus the Docker setup was very clear.
- Nice touch adding PostgreSQL initialization.
- Solid test coverage.
- Clean auth management; the middleware usage was a big plus.
A few questions/discussion points:
- I noticed there’s quite a bit of business logic inside the HTTP handlers. How would you approach keeping handlers cleaner if you were to iterate on the design?
- Was there a specific reason you chose mux for the HTTP server?
Also, what was the reasoning behind using string splitting to determine parts of the URL path? - If you had more time to deliver the project, what would you add or change?
- At a high level, what steps would you follow to deploy this service to a production Kubernetes cluster?
Thanks!
Looking forward to your thoughts!
apopsallas
left a comment
There was a problem hiding this comment.
Hello @steliosant !
Thank you for your time and effort on this assignment, and for putting together the Swagger setup, Docker configuration, and DB initialization. Those were especially helpful and appreciated.
After reviewing the project, I had a few questions about your implementation choices:
-
Interesting implementation for routing. Could you elaborate on why you chose to use string manipulation instead of mux’s built-in routing functionality?
-
I noticed the DB connection is passed from main through all layers and into the repositories as a function parameter. Could you share your thoughts on this approach versus using constructor-based dependency injection?
-
I also noticed that the description field isn’t part of the Asset model and is instead passed as a separate parameter. Could you walk me through the reasoning behind that design choice?
-
Could you share how you typically think about structuring layers and responsibilities in a larger production Go service?
Looking forward to your thoughts! Thanks again!
Hi Nikos! Thanks for the effort you put on reviewing my project. I will try to answer to all your bullets: I noticed there’s quite a bit of business logic inside the HTTP handlers. How would you approach keeping handlers cleaner if you were to iterate on the design? Indeed there is quite of a business logic into the handlers. In a different approach for keeping the handlers cleaner I would add a service layer for the business logic. In this layer I would add some logic such as: user validation, request response handling , error Mapping (Converting domain errors to HTTP status codes), HTTP concerns (Status codes, headers, response formatting), Path parsing (Extracting IDs from URL paths). This change would have made the code cleaner and would have add some benefits such as reusability and maintainability. Was there a specific reason you chose mux for the HTTP server? Also, what was the reasoning behind using string splitting to determine parts of the URL path? When I started the project(no previous Go experience) “net/http” library was the standard library for doing that. While using it I faced some limitations, for example I couldn’t extract a parameter from a path for example: in “/users/{id}/favourites” was not able to extract {id}. So the string splitting was a workaround for this limitation. I did some searching(after yours and your colleague’s comments about string splitting) and I realised that there are some alternative libraries that can do the job, like Gorilla/mux. I believe this would have been probably a better approach. If you had more time to deliver the project, what would you add or change?
At a high level, what steps would you follow to deploy this service to a production Kubernetes cluster? Preparation
|
Hi Apostolos! I really appreciate the time you took to review my project! I will try to answer to your questions. Interesting implementation for routing. Could you elaborate on why you chose to use string manipulation instead of mux’s built-in routing functionality? I noticed the DB connection is passed from main through all layers and into the repositories as a function parameter. Could you share your thoughts on this approach versus using constructor-based dependency injection?
I also noticed that the description field isn’t part of the Asset model and is instead passed as a separate parameter. Could you walk me through the reasoning behind that design choice?
If description was part of Asset, it would be:
With the current design :
Those are my thoughts on that subject, please feel free to share your opinion Could you share how you typically think about structuring layers and responsibilities in a larger production Go service? Entry Point (main.go)
HTTP/API Layer (handlers/)
Business Logic Layer (services/)
Data Access Layer (repositories/)
Data Models (models/)
In my current implementation I am mixing business logic in the handlers layer. If I had to implement it again I would have separate it by adding a service layer as well. |
Implementation of GWI go challenge by Stelios Antonopoulos