Skip to content
pimeys edited this page Dec 6, 2010 · 41 revisions

AaltoApps architecture

High level server architecture

AaltoApps runs in Amazon EC2 cloud server instance running Ubuntu Linux 10.10. The server instance uses EBS data storage for the files. Usually an EC2 instance loses all it's data when shut down with no disk space. EBS storage costs a bit more but is required to secure the data (logs, application files, configurations) if the instance is shut down. The project is written using Ruby language and Ruby on Rails web framework. The Ubuntu instance is modified by installing a HTTP server (Nginx), Rails application server (Passenger), Ruby interpreter (ruby 1.9.2), Rails framework (Rails 3.0.1), a database server (PostgreSQL 8.4) and a set of required libraries. Database and application files are saved in a separate EBS file system for easier backup possibilities and to be able to run the database in a separate server in the future.

The login process and user data is handled by ASI service running outside the main application. AaltoApps uses REST (Representational State Transfer) calls to ASI service for authentication and saves only the ASI id in it's own database, so the software can link user to his/her projects, comments and ratings.

The overall high level architecture is described in the following image:

Server instance architecture

The server has a static IP address and it receives HTTP and HTTPS requests from the client. The server uses Nginx web server as a HTTP(S) server which translates the requests for Passenger application server. Passenger handles the Rails instances which can handle only one request at a time. If all the application stacks are busy Passenger launches more instances.

The Rails stack is almost a pure MVC (model-view-controller) application. The requests are captured by a router which breaks them for controllers. E.g. http://domain.com/products/delete/123 routes by default to a controller named "ProductsController" and to an action method named "Delete". The last number represents an id, so the call deletes a product with an id "123".

The controllers are backed up by models which are saved to a database storage. A model can be e.g. a user, a product or something more abstract like a platform or category. Ruby on Rails uses an ORM (object-relational mapper) called ActiveRecord and it transforms the database data and relations to objects to be used by the controllers and views. So the controllers gather and prepare the models as instance variables which are shown in the views.

The views are for representing the data. In AaltoApps the views are mainly HTML5 and CSS3, although they can be anything like JavaScript or HAML syntax. A view gets it's data variables from controllers and render it for the user.

So in summary, user gets an access to the controllers. Controllers get the data as models and display it in views.

The insides of an EC2 instance:

AaltoApps Controllers

AaltoApps contains the following controllers:

ApplicationController

All the controllers inherit the ApplicationController. Contains the getter and setter for current_user and authentication filters to be used in all controllers.

ProductsController

Lists, shows, creates, updates and deletes products added by users.

index - lists products

GET: /products?parameters

HTTP GET parameters:

  • page (for paging the products, handled automatically by views)
  • platform (id of a platform, filters the products)
  • sort (how the products should be sorted: popularity, created_at, avg_rating, featured)
  • q (query search string for product name)

new - renders a page to create a new product, requires login

GET: /products/new

create - creates a product, requires login

POST: /products

HTTP POST parameters:

  • name
  • description
  • url
  • donate
  • category_id

show - displays a specific product

GET: /products/ID, ID = product id as an integer

edit - opens an edit view for an existing product, requires login

GET: /products/ID/edit, ID = product id as an integer

update - updates an existing product, requires login

PUT: /products/ID, ID = product id as an integer

HTTP PUT parameters:

  • name
  • description
  • url
  • donate
  • category_id

destroy - destroys an existing product, requires login

DELETE: /products/ID, ID = product id as an integer

UsersController

Lists, shows, creates, updates and deletes users in the system.

index - lists users in the system

GET: /users

show - shows a specific user

GET: /users/ID, ID = user id as an integer

new - form for creating a new user

GET: /users/new

create - creates a new user to the system

POST: /users

HTTP POST parameters:

  • username
  • password
  • email

edit - form for updating an user

GET: /users/ID/edit, ID = user id as an integer

update - updates an existing user

PUT: /users/ID, ID = user id as an integer

HTTP PUT parameters:

  • username
  • password
  • email

destroy - destroys an existing user

DELETE: /users/ID, ID = user id as an integer

SessionsController

Login and logout.

index - form for login

GET: /sessions

create - login to the system

POST: /sessions

HTTP POST parameters:

  • username
  • password

destroy - logout from the system

DELETE: /sessions

RatingsController

Product rating.

create - creates a rating for a product

POST: /product/ID/ratings, ID = id of a product as an integer

HTTP POST parameters:

  • rating

update - updates an existing rating for a product

PUT: /product/ID/ratings/R_ID, ID = id of a product as an integer, R_ID = id of a rating as an integer

HTTP PUT parameters

  • rating

PlatformsController

Lists, shows, creates, updates and deletes platforms in the system.

index - lists all platforms in the system

GET: /platforms

new - form for creating a new platform

GET: /platforms/new

show - displays a platform in the system

GET: /platforms/ID, ID = id of a platform as an integer

edit - form for updating a platform in the system

GET: /platforms/ID/edit, ID = id of a platform as an integer

create - creates a new platform

POST: /platforms

HTTP POST parameters:

  • name
  • image_url

update - updates an existing platform in the system

PUT: /platforms/ID, ID = id of a platform as an integer

HTTP PUT parameters:

  • name
  • image_url

destroy - deletes a platform in the system

DELETE: /platforms/ID, ID = id of a platform as an integer

CategoriesController

Lists, shows, creates, updates and deletes categories in the system.

index - lists all categories in the system

GET: /categories

new - form for creating a new category

GET: /categories/new

show - displays a category in the system

GET: /categories/ID, ID = id of a category as an integer

edit - form for updating a category in the system

GET: /categories/ID/edit, ID = id of a category as an integer

create - creates a new category

POST: /categories

HTTP POST parameters:

  • name
  • image_url

update - updates an existing category in the system

PUT: /categories/ID, ID = id of a category as an integer

HTTP PUT parameters:

  • name
  • image_url

destroy - deletes a category in the system

DELETE: /categories/ID, ID = id of a category as an integer

CommentsController

Creates comments in the system.

create - creates a comment to a product

POST: /products/ID/comments, ID = id of a product as an integer

HTTP POST parameters:

  • body

AaltoApps Models

Product

Has one:

  • Publisher (User)
  • Category

Has many:

  • Ratings
  • Comments
  • Platforms

Validates:

  • The presence of name, description, url, category and donate
  • The length of name is at least 3 characters
  • The length of url is at least 12 characters

Category

Has many:

  • Products

Validates:

  • The presence and uniqueness of name
  • The length of name is at least 3 characters

Platform

Has many:

  • Products

Validates:

  • The presence and uniqueness of name
  • The length of name is at least 3 characters

User

Has many:

  • Ratings
  • Published (Products)
  • Comments

Validates:

  • The presence of ASI ID

Rating

Has one:

  • User
  • Product

Validates:

  • The presence of user and product
  • The rating is a float between 1 and 5, step is 0.5

Comment

Has one:

  • Product
  • Commenter (User)

Validates:

  • The presence of commenter and product
  • The length of message body is at least 3 characters.

Session

Handles the communication with ASI server API. Stores the cookie and handles the UserConnections. Login and logout.

UserConnection

The actual REST calls are sent from here.

Views

The views are generated and handled by the controllers. Each action usually has their own view template. The view is constructed from a layout template with a header and a footer. Every GET action renders a template to the middle part of the layout.