From b01b985306240254ea85b92a39b10acb1eb2a334 Mon Sep 17 00:00:00 2001 From: tobscure Date: Fri, 19 Dec 2014 21:28:24 -0800 Subject: [PATCH] Created Architecture (markdown) --- Architecture.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Architecture.md diff --git a/Architecture.md b/Architecture.md new file mode 100644 index 0000000..e38b197 --- /dev/null +++ b/Architecture.md @@ -0,0 +1,33 @@ +Flarum’s architecture can be conceptualized as an onion with three layers: + +The innermost layer is the **core**. This layer is responsible for the domain (i.e. managing the data structures that make up Flarum.) It contains Entities, Repositories, Commands, and Domain Events. + +The middle layer is the **API**. This layer exposes a web API to read and write to Flarum’s domain. Its API endpoints call upon Commands and Repositories from the core layer. + +The outermost layer is the **web application**. This bootstraps an Ember.js application which consumes the API. + +This layered architecture allows for a large amount of flexibility and extensiblity. For example, the default Ember.js application could be replaced with a standard Laravel web app, or a native mobile app could be built using the API. By explicitly separating these layers, code becomes more reliable and testable. + +## Core + +Flarum is a dynamic application and its domain needs to be able to be extended while still having reasonably respectable, testable code. Thus, effort has been made to strike a balance between adhering to best practices, and being easy to work with and modify. + +**Entities** (e.g. Discussion, Post, User) are based on Laravel’s Eloquent ORM. They use [Permissible](https://github.com/tobscure/permissible) to define logical permission clauses. They also have inbuilt validation. + +**Repositories** are generally used to find/save/delete entities, providing a proper layer of database abstraction. However, during development so far, adhering strictly to this pattern has sometimes caused more trouble than it is worth (especially when thinking about how [Extensions]() will deal with Entities and Repositories.) Thus, the abstraction is a bit leaky. This may become apparent and need to be dealt with when [tests are written](). + +**Commands** and **Domain Events** are associated with each Entity type, in line with [this pattern](https://github.com/laracasts/Commander). **Listeners** are used to do things like update metadata (post count, last post time, etc.), format post content, and send emails. This pattern is very suitable as Extensions will easily be able to listen for Domain Events. + +## API + +Flarum’s API endpoints route to classes called **Actions**. These are essentially mini-controllers, but there is one per endpoint, and they inherit functionality to make writing endpoints easier. + +Flarum’s API endpoints are structured according to the upcoming [JSON-API spec](http://jsonapi.org). This is achieved with the help of a [package](https://github.com/tobscure/json-api). Various Serializers are defined for each type of Entity. + +## Web + +Flarum's Ember.js application is built with [ember-cli](http://ember-cli.com), and compiles many LESS and ES6 files down to a couple of CSS and JavaScript files. + +The web layer’s main responsibility is to render a page which includes these CSS/JS files, and then simply runs the Ember app. It manages assets so that Extensions will be able to add their own CSS/JS files to extend the Ember app. + +In the future, the web layer will need to support routes and render basic content before bootstrapping the Ember app accordingly (#?). \ No newline at end of file