Skip to content

Application architecture

Roni Juntunen edited this page Dec 14, 2019 · 1 revision

Application architecture

This application follows classical server client architecture and tries to also comply with MVC-standard.

Overall construction

Diagram of the overall construction of this application can be found form here. Diagram show all the main components and logic of the application.

Backend

More detailed diagram of the backend is available here

Authentication

Authentication in the backend has been implemented with custom middleware that checks weather user is authenticated or not using provided cookie or alternatively x-access-token-header field. Authentication is done by checking is there similar JWT token in authentication table with same user id that is stored inside token. JWT could be used without database checking but this is currently implemented this way for extra security since with database assisted checking it's possible to revoke tokens easily. Unfortunately there is currently no option for the user revoke access, but its possible to do easily in the future if needed. Tokens will be automatically removed from the database after 90 days.

After checking information like userId will be added to request object. This information is then easy to receive in later phases. Currently authentication checking is made for all requests even for public ones. This wastes resources on public requests and that is why behavior should be changed in the future.

Routes (View)

Routes are "view" of the backend since they are receive all api queries and sends almost all responses (invalid tokes are exceptions and handled in authentication). View components main purpose is to check that request is made according to rule and escape all possibly harmful queries. If response is okay it will be send directly to controller in escaped form.

Controllers (Control)

Controllers handles request by querying database with combined information from request and authentication. After logical processing request will be returned back to routes for response preparation. Controllers are mainly pretty straight forward and what they mainly do in this application is database error checking and handling.

Database (Model)

Database is handled using plain SQL-commands generated by scripts in the database folder. Idea of these scripts is to convert values of the objects to proper SQL query. There is nothing special with these.

Startup sequence of backend

  1. Backend will start by initializing all the necessary middlewares. First there is build in middlewares like CORS, session, cookieParser and JSON which are all used for authentication and data retrieval.
  2. All the routers will be initialized.
  3. Database will be initialized
    • If there are no tables they will be generated
    • If database is not yet up it connection will be retried every 15 seconds 10 times.
  4. Connection to port will be established
    • Via http if no server.key and server.cert is found

Frontend

More detailed diagram of the frontend may be found from here

Pages (View / Control)

Pages are main classes for View. They define layout of the page. If page consist of multiple big components page will be defined in the pages folder. If there are no multiple big components component classes will be used directly instead. In this application this is the case with sign in and sign up.

Controller components (View)

Controller components are mainly UI related. These components have controller postfix since they have some small logic and state related directly to UI. For example these components will update their state when text field is changed and knows how to send button press forward.

View components (View)

View components are mainly JSX files that don't have almost any logic. These components can show data provided by controller component via props. These components don't have their own state.

Actions and reducers / Redux (Control)

Actions and reducers will do all the real actions of the application like queries and state changes. These components will be called by view components by function callbacks using props. Results from the action will be returned after reduce back to view using props.

There are 4 different kind of actions and reducers: getPosts, getSearch, newPost and user Normally actions and reducers are tightly integrated into view their view components but user is exception to this rule. This is because user contains current login details and many components needs that information. That is why user is integrated at pretty high level in userRouter so basic information like user nickname will be available for all components.

It would have been better to integrate Redux even more deeply with view so there would have been less need for controlling in the view controllers but I didn't find any good way to do that yet. I think current situation is still pretty okay and even Redux documentation says it's fine to store UI information in states.

Containers / Redux (Model)

Containers keeps all the information provided by actions via reducers. Containers main purpose is to connect all the data and callbacks to the props that are visible to the view.

Routing (Control)

Routing is done with React router. React router is implemented in userRouter which renders correct page according to URL. userRouter also notifies reducers about URL change which is a bit hacky but resets nicely correct field in the container like in getPosts reducer it will force posts reload.

Startup sequence of fronend

  1. Application will be started from index.js which does not do much. At the moment it only start App.js
  2. App.js will initialize all Redux containers and start userRouter
  3. UserRouter check what is the current page and renders that page accordingly. It also launches checkCookie action that retrieves user information from the cookie and wires pageChange listener to React router page changes.
  4. Normally home.js will be loaded. Home.js checks should there be newPostController rendered. If this is a front page there is no such need. Then home.js will load menu and postController.
  5. Menu will check login status and update buttons accordingly.
  6. PostController will check current address and dispatch getPosts action. Results will be shown by contentView.
  7. Main page should be now fully loaded.

Search action example

Action diagram from search action can be found from here. All the other REST-api request works similarly.

Clone this wiki locally