B
Brian Candler
I'm starting to look again at available web application frameworks for Ruby
- it's been a few years since I last did. What I'm looking for is to be able
structure my application like this:
HTTP+
HTML RPC(*) SQL
<--------> user <--------> application <--------> database
interface logic
(*) e.g. DRb, or just direct invocation of a separate object
The idea here is to be able to bolt multiple front-ends onto the same
application logic. For example, you might start by having a web form for
entering new customer orders, but then you could add a SOAP interface so
they can be submitted automatically, or a batch-upload interface which
accepts CSV files.
HTTP+
HTML RPC SQL
<--------> user <--------> application <--------> database
interface -> logic
1 |
SOAP |
<--------> user <--------
interface
2
The important thing is that the business logic for (say) validating orders,
or performing a series of actions in response to submission of a valid
order, exists exactly once and so is the same regardless of how the request
came in (*).
In 'MVC' terminology, I think the "application logic" box is a Controller
with a Model sitting behind it. It will also need to provide an interface to
query the state of the Model, unless the Model directly exposes a read-only
view to the UIs.
My first port of call for looking at modern frameworks is Rails. Looking
through the Rails tutorials, I get the impression that a Rails "controller"
is responsible for three things:
1. Parse the HTTP request, e.g. extract relevant params()
2. Validate the request and perform any database updates directly
3. Decide which view to send back to the browser (which in turn also
queries the database directly)
Is that a fair summary?
Would it also be true to say that in Rails, the de-facto model is just a
bunch of database tables, with a separate ActiveRecord facade sitting in
front of each table? For example, if a particular action requires four
tables to be updated, would the controller typically get four ActiveRecords,
modify them and write them all back? If so, this seems to bundle the 'user
interface' and 'application logic' parts together more closely than I'd
like.
I expect I can write my own application logic server, and use Rails as a
front-end to submit RPC requests to it. This means that the controllers
would do very little though, just:
- bundle up the paramters and submit an RPC request for an action
- look at the response (success or fail)
- submit an RPC request to get model state
- generate a suitable HTML page response
It looks like I'd hardly be using any of Rails - just the HTML templating
and perhaps session tracking. Maybe then a more lightweight framework would
be better suited? (**)
I wrote a tiered application along these lines a few years ago for a
different employer. I ended up writing a framework to handle the FCGI main
loop; compile Amrita templates on demand and cache them; and handle
unexpected exceptions, displaying a suitable page back to the browser.
Perhaps there's a simple framework I can use which will avoid having to
re-write this from scratch?
Thanks for your ideas.
Regards,
Brian.
(*) This could be quite complex logic. For example, "create order for
customer" might perform a bunch of validation, do a credit check in some
circumstances, add an order line into a database, send a message to a
billing system, and send messages to service provisioning platforms.
(**) I can imagine cases where it might make sense not to stick rigidly to
the tiered approach. As mentioned above, maybe the UI could be allowed to
read the model state directly; this suggests
HTML RPC SQL
<--------> user ---------> application <--------> database
interface logic |
^ .
` . . . . . . . . . . . . . . . . . .
read-only query path
In that case, if the application logic was already using ActiveRecord as its
model, then Rails would probably be a good choice for the UI. You'd share
the ActiveRecord model definition, and give the UI read-only DB credentials.
However in my case I may need to force all data accesses via the
"application logic" layer, in particular to provide a central point of
enforcing access control policies - i.e. who can read what.
I can also see that the UI might legitimately need R/W access to a database
for its own private purposes (for example, the UI could be responsible for
assembling a shopping cart, before submitting a completed order). In this
case the database is just a UI scratchpad, entirely separate from the
business model. Therefore, you might want something like ActiveRecord
available even with the tiered approach.
- it's been a few years since I last did. What I'm looking for is to be able
structure my application like this:
HTTP+
HTML RPC(*) SQL
<--------> user <--------> application <--------> database
interface logic
(*) e.g. DRb, or just direct invocation of a separate object
The idea here is to be able to bolt multiple front-ends onto the same
application logic. For example, you might start by having a web form for
entering new customer orders, but then you could add a SOAP interface so
they can be submitted automatically, or a batch-upload interface which
accepts CSV files.
HTTP+
HTML RPC SQL
<--------> user <--------> application <--------> database
interface -> logic
1 |
SOAP |
<--------> user <--------
interface
2
The important thing is that the business logic for (say) validating orders,
or performing a series of actions in response to submission of a valid
order, exists exactly once and so is the same regardless of how the request
came in (*).
In 'MVC' terminology, I think the "application logic" box is a Controller
with a Model sitting behind it. It will also need to provide an interface to
query the state of the Model, unless the Model directly exposes a read-only
view to the UIs.
My first port of call for looking at modern frameworks is Rails. Looking
through the Rails tutorials, I get the impression that a Rails "controller"
is responsible for three things:
1. Parse the HTTP request, e.g. extract relevant params()
2. Validate the request and perform any database updates directly
3. Decide which view to send back to the browser (which in turn also
queries the database directly)
Is that a fair summary?
Would it also be true to say that in Rails, the de-facto model is just a
bunch of database tables, with a separate ActiveRecord facade sitting in
front of each table? For example, if a particular action requires four
tables to be updated, would the controller typically get four ActiveRecords,
modify them and write them all back? If so, this seems to bundle the 'user
interface' and 'application logic' parts together more closely than I'd
like.
I expect I can write my own application logic server, and use Rails as a
front-end to submit RPC requests to it. This means that the controllers
would do very little though, just:
- bundle up the paramters and submit an RPC request for an action
- look at the response (success or fail)
- submit an RPC request to get model state
- generate a suitable HTML page response
It looks like I'd hardly be using any of Rails - just the HTML templating
and perhaps session tracking. Maybe then a more lightweight framework would
be better suited? (**)
I wrote a tiered application along these lines a few years ago for a
different employer. I ended up writing a framework to handle the FCGI main
loop; compile Amrita templates on demand and cache them; and handle
unexpected exceptions, displaying a suitable page back to the browser.
Perhaps there's a simple framework I can use which will avoid having to
re-write this from scratch?
Thanks for your ideas.
Regards,
Brian.
(*) This could be quite complex logic. For example, "create order for
customer" might perform a bunch of validation, do a credit check in some
circumstances, add an order line into a database, send a message to a
billing system, and send messages to service provisioning platforms.
(**) I can imagine cases where it might make sense not to stick rigidly to
the tiered approach. As mentioned above, maybe the UI could be allowed to
read the model state directly; this suggests
HTML RPC SQL
<--------> user ---------> application <--------> database
interface logic |
^ .
` . . . . . . . . . . . . . . . . . .
read-only query path
In that case, if the application logic was already using ActiveRecord as its
model, then Rails would probably be a good choice for the UI. You'd share
the ActiveRecord model definition, and give the UI read-only DB credentials.
However in my case I may need to force all data accesses via the
"application logic" layer, in particular to provide a central point of
enforcing access control policies - i.e. who can read what.
I can also see that the UI might legitimately need R/W access to a database
for its own private purposes (for example, the UI could be responsible for
assembling a shopping cart, before submitting a completed order). In this
case the database is just a UI scratchpad, entirely separate from the
business model. Therefore, you might want something like ActiveRecord
available even with the tiered approach.