nairobi-gophers / fupisha

Fupisha is a modern url shortening service. Fupisha is a swahili word for Shorten.
MIT License
21 stars 10 forks source link

Give more thoughts to app structure #3

Closed cholthi closed 3 years ago

cholthi commented 4 years ago

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).

basebandit commented 4 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?

cholthi commented 4 years ago

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.

cholthi commented 4 years ago

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

basebandit commented 4 years ago

@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.

basebandit commented 4 years ago

To avoid confusion I have changed the name from model to schema. See Project_Layout_Proposal

cholthi commented 4 years ago

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 commented 4 years ago

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.

basebandit commented 4 years ago

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.

basebandit commented 4 years ago

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.

cholthi commented 4 years ago

To take your example, in the current layout, how w'd switch between different implementations of the database stores?

cholthi commented 4 years ago

Yes, you are right things will become clear as we write code.

iampato commented 3 years ago

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

basebandit commented 3 years ago

Hi @iampato, feel free to make a pr, or even share ideas. Note: All ideas are welcomed. Thank you for your feedback.