SaaS Architecture
The Web as a Client-Server System
The Web is a client/server architecture and fundamentally request/response oriented.
Client-Server
architecture is a high level architecture where clients and servers are
specialized in specific tasks: clients ask questions on behalf of
users, servers wait for and respond to questions, serve many clients.
Client-Server is an architectural pattern, it has another alternative P2P (Peer to Peer) architectures.
A Design patterns capture common structural solutions to recurring problems.
Domain Name System (DNS) is another kind of server that maps names to IP addresses.
Web at 100,000 feet |
HTTP (Hypertext Transfer Protocol) is an ASCII-based request/reply protocol used for transferring information on the web
- HTTP requests include request method (GET, POST, etc.), Uniform Resource Identifier (URI), HTTP protocol version that is understood by the client, headers for transferring extra informations about the request.
- HTTP responses from web server include protocol version, status code (2xx all is well, 3xx resource moved, 4xx access problem, 5xx server error), headers and response body.
Early Web 1.0 problem was how to guide a user through a flow of pages as HTTP is stateless. Many options were chosen:
- User IP address to identify returning user (problems: public computers, multiple users sharing same IP)
- Embed per-user junk into URI query string (problems: breaks caching)
- Cookies: per-user user state can be used for lots of things like customization (My Yahoo), click/flow tracking, authentication (logged in or not),
Which of the previous things could be implemented on the client side? which ones shouldn't be and why?
3-tier shared-nothing architecture & scaling
Dynamic content generation
In
early days, most web pages were (collection of static pages) plain old
files. Later, when e-commerce sites appeared, a program was running to
generate pages. Originally, templates with embedded code "snippets".
Eventually, code become "tail that wagged the dog" and moved out of the
Web server.
Software as a Service
Sites that are really programs have to deal with many things (frameworks support these common tasks):
- map URI to correct program & function?
- pass arguments between web site pages
- invoke program on server
- handle persistent storage
- handle cookies
- handle errors
- package output back to user
Sharding vs. Replication
For scaling a Web application is crucial to be able to scale persistence layer. Two techniques are commonly used:
- Sharding: consists of partitioning data across independent "shards" (e.g. user profile table), it scales great, but bad when operations touch more than one table (e.g. when running join queries),
- Replication: consists of replicating all data everywhere, this makes running multi-table queries faster, but hard to scale as writes must propagate to all copies which create a temporary inconsistency in data values.
Summary
Browser
requests web resource (URI) using HTTP which is a simple request-reply
protocol that relies on TCP/IP. In SaaS, most URI’s cause a program to
be run, rather than a static file to be fetched.
HTML is used to encode content, CSS to style it visually
Cookies
allow server to track client (e.g. including a handle to server-side
information): browser automatically passes cookie to server on each
request, and server may change cookie on each response
Frameworks
make all these abstractions convenient for programmers to use, without
sweating the details and help map SaaS to 3-tier, shared-nothing
architecture
Model-View-Controller
The MVC design pattern
Separate
organization of data (model) from presentation (view) by introducing
controllers that mediate user actions requesting access to data, and
present data for rendering by a given view.
Web apps may seem obviously MVC by design, but as an architecture other alternatives are possible.
- Page Controller where an HTML page is associated in a one to one fashion with a program (e.g. Ruby Sinatra).
- Front Controller where a single program handle all user requests and render corresponding view (e.g. J2EE servlet)
- Template View where code snippets are inserted directly into the view for customizing rendering based on stored data and user request (e.g. PHP).
Models, Databases, and Active Record
In-Memory vs. In-Storage objects
In-memory object are marshaled/serialized into in-storage objects. The later are unmarshaled/deserialized in the first ones.
How to represent persisted object in storage?
Basic operations on objects are Create, Read, Update, Delete (CRUD).
ActiveRecord gives to every model common mechanisms so that it knows how to CRUD itself.
Rails
Models store data into Relational Databases (RDBMS) where each Model
gets its own database table. A schema is a collection of all tables and
their structure.
- A row is one Model instance, it has a unique value for its primary key, and all rows have similar structure.
- Each colon stores value of an attribute of the model.
ActiveRecord vs. DataMapper |
DataMapper is an alternative to ActiveRecords
that associates separate mapper with each Model to abstract underlying
storage system and to be able to work with any RBDMS. DataMapper is used
by Google App Engine, it scales very well but can't exploit RBDMS
features to simplify complex queries (e.g. join) and relationships.
Controllers, Routes, and RESTfulness
Routes
In MVC, each interaction that user can do is handled by a controller action, i.e. method that handle this interaction. A route maps <HTTP method, URI> to controller action.
For instance, Route "GET /movies/3" is mapped to Action "Show info about movie whose ID=3".
Rails Routing subsystem:
- dispatch <method, URI> to correct controller action,
- provides helper methods that generate a <method, URI> pair given a controller action,
- parses query parameters from both URI and form submission into a convenient hash,
- built-in shortcuts to generate all CRUD routes (though most apps will also have other routes)
Example of how Rails manage a given user request GET /movies/3/edit HTTP 1.0
- Matching route: GET /movies/:id/edit {:action=>"edit", :controller=>"movies"}
- Parse wildcard parameters: params[:id] = "3"
- Dispatch to edit method in movies_controller.rb
- To include a URI in generated view that will submit the form to the update controller action with params[:id]==3, call helper: update_movie_path(3) # => PUT /movies/3
The
idea behind REST is to create self-contained requests that specify what
resource to operate on and what to do to it instead of using cookies,
setting them on each user request and do multiple HTTP requests between
user browser and Web application.
A service (in the SOA sense) whose operations are like this is a RESTful service: its RESTful URIs name the operations.
Template Views and Haml
Template View pattern
A Template View consists of markup with selected interpolation to happen at runtime, it generates HTML that will be consumed by a human.
In
early days, this was the application, e.g. PHP you start writing
views than open <?php to write usually, values of variables
or result of evaluating short bits of code.
An alternative to this pattern is Transform View to generate JSON/XML instead of HTML, in case you application is called as a service by another application.
Template View vs. Transform View |
Don't put code into views as MVC advocates thin
views & controllers, also it's awkward to put code into Haml
pages. An alternative to Haml is html.erb for embedded Ruby templates
(just like PHP).
Helpers are methods that prettify objects for including in views, they have their own place in Rails app.
Summary & Reflections: SaaS Architecture
2008 "Rails doesn't scale"
- Scalability is an architectural concern that is not confined to language or framework
- The stateless tiers of 3-tier arch do scale, with cloud computing, just worry about constants
- Traditional relational databases do not scale, instead various solutions combining relational and non-relational storage (“NoSQL”) scale much better (DataMapper works well with some of them)
- Intelligent use of caching can greatly improve the constant factors
Architecture is about Alternatives
Summary: Architecture & Rails
Model-view-controller is a well known architectural pattern for structuring apps. Rails codifies SaaS app structure as MVC:
- Views are Haml or embedded Ruby code, transformed to HTML when sent to browser
- Models are stored in tables of a relational database, accessed using ActiveRecord
- Controllers tie views and models together via routes and code in controller methods
Aucun commentaire:
Enregistrer un commentaire