Closed cholthi closed 3 years ago
Hi @cholthi thats a nice suggestion. In line with your suggestion. I have drafted two other project layout proposals. What is your opinion?
Hi @basebandit thats is great. I like the first layout and looks more civil to my eyes. I would suggest a small change though.
It would be semantic if you change the store
directory to model
, then put store
under it. Basically am saying you swap the folder names. The reason for this is, the model
is more common way to name data layer of the application while the store
is the implementation detail of a model
. Overall, i like the changes you made.
Later if we need, say, a different sending email client. We could a write a small interface that our app depend on to send emails and then we add a directory like email
with implementations of different clients but this is never required as the app will have its own default client for sending mails
@cholthi I acknowledge you are referring to MVC which I have no objection to however I am trying to avoid some of mistakes we might try to copy from other languages that utilized MVC and choose an approach that can be scalable and more importantly feel like Go. The idea behind store
is that it represents a database inside which has subdirectory named after the database we are supporting lets say mongodb
or postgres
each of these will hold types
specific to each database and more importantly they will all implement the same store
interface. Look at store.go
.
Just to emphasize I will quote this phrase from john calhoun on some of the caveats of MVC when applied to Go projects directly.
You will need to define resources more than once
In Rails we might define a model once and then expect it to work across our entire application. There are several ways we do this, but it mostly revolves around:
- Creating methods that translate data
- Creating wrapper types, like a decorator
While it is possible to create a Go web application where the only time you define your resources is in the models package, it is more likely that you will eventually need to define a second version of each resource. For instance, imagine we were rendering a User for a JSON response - if we were to use the models definition of a user we would need to add all of those json struct tags to the models package even though it has nothing to do with the code there. We would also potentially need to write custom marshalling code there to handle the fact that what we store in the database isn’t exactly what we want to render to the user.
To avoid confusion I have changed the name from model to schema. See Project_Layout_Proposal
You want every store to provide their own implementations of the application entities. That will be redundant and unnecessary as the Go standard library provides sql
package that abstracts the database access into uniform API. The point at which you would like to extent from is the app specify DBAL.
Ideally, they should be single user
and url
objects which make use of the app specify DBAL
and in turn DBAL
makes use of store implementations under store
directory. This does not look much MVC to me except we w'd just organize all db related code inside model directory.
You want every store to provide their own implementations of the application entities. That will be redundant and unnecessary as the Go standard library provides
sql
package that abstracts the database access into uniform API. The point at which you would like to extent from is the app specify DBAL.
@cholthi It might first appear redundant but that is how you support multiple databases at the same time. Lets say we wished to support a relational
database and the first version was shipped with support for non-relational
database. In such a case you will only have to change the type of database to be used in the configuration file or env variable and the system will be able to pick that up.
For this project I do not wish to use the MVC
in the classical sense and hence the reason for a more pragmatic but simple approach. IMO things will fall in place as we progress.
To take your example, in the current layout, how w'd switch between different implementations of the database stores?
Yes, you are right things will become clear as we write code.
To be honest, I am afraid of doing a PR on this, since its so opinionated, I respectfully is the first I noticed it may need some work
Hi @iampato, feel free to make a pr, or even share ideas. Note: All ideas are welcomed. Thank you for your feedback.
Since this is a learning project, I would suggest a more ground up development methodology. To make this palatable to all Gophers of varying levels. I would suggest starting with a very simple structure and with special focus on architecture such as interface based design. Make it so that every gopher will find a layer to contribute. Personally am not a fun of nested directory structure. The layer of application that deserve they own layer or directory is the "storage" as this will be extended by developers with own storage engines. But even the storage main driver will be at app root. Directories can be added later as extension points conforming to main app interfaces but they should not play any role in the app build process. Am a huge a fun of flat out structure as it friendly to starters at least it did for me when learning Go language. All developers using Go came to it because of its simple syntax and being scared off by other languages. ( pun intended).