Skip to content
Permalink
Browse files

Merge pull request #37 from tomkadwill/architechture_fixes

Fixes for architecture guides
  • Loading branch information...
jodosha committed Jun 24, 2015
2 parents e6a7b09 + 596a8e5 commit 2828192c99a388f8d319df934ed33e9b34b286ed
@@ -6,17 +6,17 @@ title: "Lotus - Guides - Architectures: Application"

## Application

This is an alternative Lotus architecture that should be used only at the later stage of a project, when we have already considered to extract a microservice.
This is an alternative Lotus architecture that should be used only at the later stage of a project, when we have already considered extracting to microservices.

Lotus applies the [Monolith First](http://martinfowler.com/bliki/MonolithFirst.html) principle.
In the early days of our product, we are moving fast and it's more convenient to keep all the components in the same repository and the same Ruby process.
In the early days of our product, we are moving fast and it's more convenient to keep all the components in the same repository and in the same Ruby process.

This is possible with Lotus [Container architecture](/guides/architectures/container) and we **strongly** suggest to use it for new projects.
This is possible with Lotus [Container architecture](/guides/architectures/container) and we **strongly** suggest using it for new projects.

Application architecture is suggested for small web components.

To be more precise, it can handle well a large amount of code, and it has a structure really similar to Ruby on Rails applications.
However, we want to offer a different guidance, where large projects should use different components (Container), instead of using the same component for everything.
To be more precise, it can handle a large amount of code, and it has a structure that is similar to Ruby on Rails applications.
However, we want to offer a different approach, large projects should use different components (Container), instead of using the same component for everything.

### Anatomy Of An Application

@@ -65,10 +65,9 @@ Our core application still lives in `lib/` because we still want to apply the [C

Imagine we have built a product named _Bookshelf_, that is an online place where customers share their opinions about their readings, and they are also able to purchase books within our app.

We run our business since three years now and it has a decent monthly revenue.
During this amount of time we moved fast to implement a lot of features to make it appealing for the market.
We have been running our business for three years now. During this time we moved fast to implement new features intended to make it more appealing to the market.

We went for the Container architecture, and now we have a few compontents such the admin pane, that were useful to keep in the same Ruby process, but now we want to move into a separated server.
We went for the Container architecture, and now we have a few components such the admin pane, that were useful to keep in the same Ruby process, but now we want to move to a separated server.
Theoretically all we need to do is to move it from `apps/admin` into a different repository and deploy it separately.

However, there are some configuration files that we want to let Lotus generate for us.
@@ -7,21 +7,21 @@ title: "Lotus - Guides - Architectures: Container"
## Container

This is the default Lotus architecture.
We **strongly** suggest to use it for your next product.
We **strongly** suggest using it for your next product.

It applies two principles: [Clean Architecture](https://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html) and [Monolith First](http://martinfowler.com/bliki/MonolithFirst.html).
It utilises two principles: [Clean Architecture](https://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html) and [Monolith First](http://martinfowler.com/bliki/MonolithFirst.html).

### Clean Architecture

The main purpose of this architecture is to enforce a **separation of concerns** between the **core** of our product and the **delivery mechanisms**.
The first is expressed by the set of **use cases** that our product implements, while the latter are interfaces to make these features available on the outside world.
The first is expressed by the set of **use cases** that our product implements, while the latter are interfaces to make these features available to the outside world.

When we generate a new project we can find two important directories: `lib/` and `apps/`.
They are home to the main parts described above.

#### Application Core

We implement a set of functionalities, without worrying about how they can be exposed on the outside world.
We implement a set of functionalities, without worrying about how they can be exposed to the outside world.
This is the **cornestone** of our product, and we want to be careful on how we manage dependencies for it.

`Lotus::Model` is the default choice for persisting our Ruby objects.
@@ -57,7 +57,7 @@ For this purpose we have a separated concept [repositories](/guides/models/repos

For each entity named `Book` we can have a `BookRepository`.

We can add as much as directories that we want, such as `lib/bookshelf/interactors` to implement our use cases.
We can add as many directories that we want, such as `lib/bookshelf/interactors` to implement our use cases.

#### Delivery Mechanisms

@@ -87,17 +87,17 @@ apps/web
Let's have a quick look at this code.

The file `apps/web/application.rb` contains a Lotus application named `Web::Application`, here we can configure all the settings for this **component** of our project.
Directories such as `apps/web/controllers`, `views` and `templates` will contain our [actions](/guides/actions/overview), [views](/guides/views/overview), [templates](/guides/views/templates).
Directories such as `apps/web/controllers`, `views` and `templates` will contain our [actions](/guides/actions/overview), [views](/guides/views/overview) and [templates](/guides/views/templates).

Web assets such as javascripts and stylesheets will be automatically served by the application.

### Monolith First

Our default application `Web` can be used as UI interface for our customers.
At a certain point of our story, we want to manage our users with an admin pane.
Our default application `Web` can be used as a UI interface for our customers.
At a certain point in our story, we want to manage our users with an admin pane.

We know that the set of features that we're going to introduce, clearly don't belong to our main UI (`Web`).
On the other hand, it's **too early** for us to implement a microservices architecture, only for the purpose of help our users to reset their password.
We know that the set of features that we're going to introduce, clearly doesn't belong to our main UI (`Web`).
On the other hand, it's **too early** for us to implement a microservices architecture, only for the purpose of helping our users reset their password.

Lotus has a solution for our problem: we can generate a new app that lives in the same Ruby process, but it's a separated component.

@@ -8,31 +8,31 @@ Lotus is a **modular** web framework.
It scales from **single file HTTP endpoints** to **multiple Lotus (or Rack based) applications in the same Ruby process**.

Each application is a component to our product.
It can be the user web facing UI, an admin pane, an HTTP API, metrics etc..
It can be the user web facing UI, an admin pane, a HTTP API, metrics etc..

Splitting these parts since the early days of development, helps us to follow the [monolith first](http://martinfowler.com/bliki/MonolithFirst.html) principles.
We want to achieve fast times for our MVP, and have a tight feedback loop.
Splitting these parts from the beginning, helps us to follow the [monolith first](http://martinfowler.com/bliki/MonolithFirst.html) principles.
We want to achieve fast iterations for our MVP, and have a tight feedback loop.
The most natural approach is to build all our components **together** in the same code base.

Once our application grows in complexity we can think to extract each component into a standalone [microservice](http://martinfowler.com/articles/microservices.html).
Once our application grows in complexity we decide to extract each component into a standalone [microservice](http://martinfowler.com/articles/microservices.html).

## Container

To make this possible, Lotus default architecture is called [**Container**](/guides/architectures/container).
To make this possible, Lotus' default architecture is called [**Container**](/guides/architectures/container).
It hosts several applications in the same Ruby process.

Each component (application) has its own Ruby namespace (eg `Web` or `Admin`) that is a strong boundary between them.
When (and **if**) we want to extract one of them, we can easily do it.

In other words, Lotus is providing gentle guidance to help building component based applications.
We **strongly** suggest to start your next project with this architecture.
In other words, Lotus is providing gentle guidance to help build component based applications.
We **strongly** suggest starting your next project with this architecture.

## Application

[**Application**](/guides/architectures/application) architecture can be used for small components.

Imagine we have build a big and successful product (with Container) that now needs a small application to report daily/weekly/monthly revenues.
Instead of add yet another component to our main product, we can use a **single purposed** application (microservice) for our need.
Instead of adding yet another component to our main product, we can use a **single purposed** application (microservice) for our needs.

We suggest to use this architecture only at the later stage of your product life.
We suggest using this architecture only at the later stage of your products lifecycle.

0 comments on commit 2828192

Please sign in to comment.
You can’t perform that action at this time.