4. Objectives
● Find a way to create generic, distributed DB
oriented applications
● One backend, multiple frontends, same
functionality:
○ web
○ mobile
○ desktop
● Rapid app development for the backend
○ Avoid boilerplate code
○ Adhere to the DRY principle
○ Generate as much code as possible
○ Have a predictible API
5. Solutions
● Implement only the business logic in Perl
● Expose it through an API
○ REST
○ SOAP
○ RPC
○ WSDL
● Services Oriented Architecture
6. Solutions
Chosen one is the REST architecture:
● The simplest to implement (from server and
client perspective)
● Uniform interface
○ simplifies and decouples the architecture
● Stateless - each request can be treated on a
different machine
○ Horizontal scalability
9. Implementation
Methods needed to implement for each
resource:
● list - returns a collection of resources (list of
users)
● show - return an individual resource (1
user)
● create - create a new resource
● delete
● update
10. Implementation
The above operations:
● each corresponds to a DB CRUD operation
● each can get implemented in a controller
method
● each can be implemented in a generic way:
○ get parameters, do stuff, return json
14. sub update{
my $self = shift;
my $result_rs = $self->app->model
->resultset( $self->{resource} )
->search_rs(
{ id => $self->param('id') },
);
return $self->render_not_found
if ( scalar( ( $result_rs->all ) ) == 0 );
$result_rs->update_all( $self->{_payload} );
$result_rs->result_class('DBIx::Class::ResultClass::
HashRefInflator');
my @result = $result_rs->all();
return $self->render_json( @result );
}
15. Steps for having REST
1. Create the DB tables
2. Generate the DBIx::Class models with
DBIx::Class::Schema::Loader
a. add the relationships between models
3. Create the controllers which inherit from the
Base controller
4. (optional) Override the desired methods (ie -
customize the business logic)
5. Create the routes to Mojolicious
16. Conclusions
● Very fast to develop
○ There are only 6 steps
■ 4 of them are, or can be, automated
● Completely DRY
○ define the table structure only once - when it is
created
○ you write a column name only when you need to do
something special with it (validate for example)
● Very easy to test
○ end to end testing can be done with simple curl
operations
17. End
Sample app (with the generic controller) can be
found on github:
https://github.com/tudorconstantin/expense-
tracker
The generic controller:
https://github.com/tudorconstantin/expense-
tracker/blob/master/lib/ExpenseTracker/Cont
rollers/Base.pm