MVC web service + web application design that maximizes code reuse - web-services

I am using an PHP MVC framework (Yii, but my question could apply to most MVC frameworks) to create a project that should include a web application (website) and RESTful web service. I am facing an early design decision on how to logically separate the application and service logic. Here are some true facts:
The web app and web service will share a lot of functionality and only differ in rendered format (View vs JSON)...
...But, the web app and web service will have some unique features (ie, there will be things that the web app does that the service does not, and vice-versa)
Here are my desires:
I would like to share the common functionality's implementation as much as possible
I do not want the Controller to become unwieldy as a result of combining web service/web application logic
I have a a slight distaste for creating separate web service and web app controllers, especially when they overlap in Actions (other than the rendered format)
I do not want to have the web site consume the web service unless it is really a necessary design decision; I will lose out on a lot of built-in features that use database interfaces and/or have to create classes that conform to available IDataSource and other such interfaces by hooking it up to the web service; also there could be a slight performance decline.
I have thought about it a bit and come up with some solutions below. Please let me know which of these you think would meet my wants or let me know if my wants are not reasonable/counter-productive.
Implement completely separate controllers for WebApp and WebService (modularize the two so that they share no code)
Implement separate controllers for WebApp and WebService, but create methods that do the heavy lifting and call those methods to share implementation - for example, if I wanted to do a item/findBySomeCrazyCriteria I would route to the appropriate controller depending on the URL, but each controller would reference some FindItemsBySomeCrazyCriteriaFunction() defined elsewhere.
Make the web app consume the web service (which would require me to expand the planned functionality of the service)
Implement one controller for both WebApp and WebService, which extends from a BaseController that includes generic hooks for REST type stuff in terms of $this->getModel()` and use overrides where necessary
Anything else
Although my question is related to Yii, I feel like this must have come up in the past for many developers. I would like to know what you did/what you recommend to move forward. I am concerned that if I choose the wrong approach I will "break MVC" or somehow regret it later.

Note: you should not worry about "breaking the MVC". Since you have chosen to use Yii, that part has already happened.
The root of the problem lays in the fact that your controllers do a lot of stuff (and thus, violating SRP). What you call "controllers' actually contain also the application logic (that should be part of model layer) and UI logic (that normally would be part of view instances).
What you should have there is a single application, with one model layer and two presentations (what you refer to as "web application" and "web service"). The controllers should be a slight a possible.
You should move the application logic to the service layer through which then the presentation layer would interact with model. You would end up with a lot lighter controller. Then you could be able to provide a separate set of controllers/view for each of the presentations that your project needs with no or minor code duplication.

I would recommend against writing multiple controllers. It is a much better option to keep your domain logic in the models, rather than controllers. Your controllers should only act as the gateway to the logic and serve them in whatever form the client requests eg. as a JSON encoded response or through a view. It would be best if you just keep the task of identifying the client requirements and after obtaining the results from the model translating the response in an appropriate form.
This flow can be streamlined with suitable helpers and a well implemented routing sub-system so that detection of client requirements becomes effortless.
eg. /user/subscriptions.html will fetch an html page where as /user/subscriptions.json will fetch a JSON response.

Related

what parts of django MVC becomes irrelevant when using django + REST framework?

Started learning Django lately.
To make long story short - If I choose to combine:
django framework in my server side
REST as the middleware layer
some of the client side frameworks (such as React, Angular, etc)
which of django's MVC components will become irrelevant?
I presume that the templates components. Are there any other fundamental components (model/view ...) that won't be necessary in this case?
Assuming based on your post that you are using Django just to pull data from a database and serve it back to a client in JSON format, and that your templates will be rendered client-side (using, e.g. Angular) then you are correct that you likely won't be needing Django templates. However, you would still need some sort of models (whether you use Django models or something else) and also would need controllers (which Django calls views) in order to:
Do URL routing (that is, bind some URL to some controller/view
function).
Do some kind of server-side processing. Even if your app
is a single-page app and does a lot of client-side processing,
you'll still likely need to implement different kinds of business
requirements and validation on the server side. Some of these
requirements you can likely attach to the models, but others you may
need to implement in controllers.
So while your controllers (aka views) may be a lot "skinnier" due to the way you're structuring your app, they'll still be necessary to some extent. Models will always be necessary if you want some clean and consistent API to your DB.
EDIT: To expand more on this--while there is a Python library called Django REST Framework, it's really just there to assist you in building RESTful APIs. You can certainly build a RESTful API yourself using Django without leveraging it or any additional libraries. As the answer from user D. Shawley states in response to this question -- What exactly is RESTful programming? -- a RESTful API is basically just one where resources are identified by a persistent identifier (in this case, URIs), and where resources are manipulated using a common set of verbs (in this case, HTTP methods like GET, POST, DELETE, etc). So using this idea of URIs as nouns and HTTP methods as verbs, your Django framework might support the following RESTful operations:
GET https://your-app.com/product/123 - this operation fetches a product identified by the ID 123
POST https://your-app.com/product - this operation creates a new product
PUT https://your-app.com/product/123 - this operation updates a product identified by the ID 123
DELETE https://your-app.com/product/123 - this operation deletes a product identified by the ID 123
The data that come back from these operations doesn't necessarily need to be in any particular format (be it JSON, XML, or something else). In an application that closely adheres to the principles of REST, the client (consumer of your RESTful API, in this case your front-end app) would be able to specify (using the HTTP Accept header) which format they want to consume the data in.
I hope that's not too confusing, but really I want to make it clear that REST architecture is just a set of principles, and APIs that web programmers develop may not necessarily adhere to these principles 100%. Whether it's necessary for your application to strictly adhere to RESTful principles depends on your particular requirements. One question to ask yourself then is what are you hoping to accomplish by building a RESTful API using Django? For a lot of developers, the answer is simply "so that I have an easy-to-use interface for my Angular/React/etc. app to retrieve and update server-side resources."

Symfony2 website and RESTful API

I'm currently developing a web application, that relies heavily on mobile and desktop clients consulting the web server for information. This can be accomplished nicely making a RESTful API available to handle this. So my idea is to have an application acting as the "platform" which handles all the real business logic and database information behind the curtains.
My plan is to make the platform using symfony2 and OAuth 2.0 authentication mechanisms, combined with RESTful web services.
Now my real dilema comes on the website component. Ideally I would like to think of the website as yet another client that asks this REST platform for information, and completely separate it from the platform itself.
To make it a little bit more clear, let's say we are making a blog with this architecture, so one would have a "platform/backend" that provides a rest service to list articles, for example: /articles/5. This on the backend, and with symfony2/doctrine means that the app has an Article model class, and these can be requested from the DB. A simple controller queries for the Article number 5 and returns all the information in JSON format.
Now the website on this example, could just do the easy thing and also have an Article entity and just query the database directly, but I think it would be cleaner if it could just talk to the platform through it's REST api and use that information as a "backend" for the entities.
So the real question would be, is there anyway to support this kind of design using symfony2? Have entities rely on a REST api for CRUD operations? Or I'm just better off making the platform/website a single thing and share a "CoreBundle" with all the generic entities?
There is nothing in Symfony that prevents you from doing you want.
On the client side you could use Backbone.js or Spine.js.
Have a look at FosRestBundle, it makes your life much easier to create api:
https://github.com/FriendsOfSymfony/FOSRestBundle/blob/master/Resources/doc/index.md

When building web apps in clojure, where should preperations for a page belong?

In web frameworks like ruby on rails, any database queries needed to handle a specific request happen before a page is passed to the client in a controller class, but there's nothing like that for clojure. Where should database queries and stuff like that be handled in a clojure web app? My gut tells me to call a function within a hiccup page and generate the HTML within that function, but I'm not really sure. Thank you for your time and consideration.
There aren't that many "full stack" web frameworks in Clojure and as far as I know most Clojure web applications aren't built with one. There is a collection of frameworks and tools that handle a variety of things, but you'll likely develop your application using these components as building blocks. You have a choice of routing functions, authentication, view rendering, templating, RESTful web services and persistence.
Where particular things should go in your application depends on your architecture - a typical, 3-tier MVC web application looks different from a full blown scalable app that's using CQRS, CEP and other fancy patterns that help you build the next Facebook or Twitter.
If you design your web app conceptually with a 3-tier MVC architecture in mind, you'll have a clear separation between your view layer, business logic, and persistence layer. Like Alex said in his answer - it's probably the Controller that ties these things together. If you don't have complex business logic, your controller will likely call functions from your persistence layer directly before passing it on to the logic that builds your views.
For some situations, it might be useful to pull in data from your persistence layer in a "middleware" — that is a function that gets called by Ring every time a request comes in. This could be the stored information about a logged in user for example.
A number of options for your building blocks: Mature Clojure web frameworks?
Most (all?) of Clojure's routing/request handling frameworks are built on top of Ring. An overview of what that looks like is here: http://brehaut.net/blog/2011/ring_introduction
IMO, whichever code generates your views should call the function, and use the result of the function to dictate how to render the view. Looked at from the Clojure perspective, Controllers could be seen as functions that are called by the router.

What's the best way to split a Grails application into web service(s) and a presentation?

I have a fairly conventional Grails application. It's monolithic; although it's somewhat split into plugins along functionality lines, it is built into a single war for deployment. Due to company architectural constraints, I need to consider isolating the app's persistence into a web service (or series of web services). What's the best approach to dividing a Grails application into a persistence service and a presentation application?
Put your domain classes in a Grails plugin, and have two distinct Grails applications, one for your web front-end and one for your web service. Both access the database directly, but code for persistence is not duplicated.
Here is a blog post that have some more details on how to realize that.
I don't have an out-of-the-box solution for your problem, and I don't believe there is one. I'll just explain the solution I use and what I would consider in your case.
In my organisation, our approach is to separate our applications in a Grails back-end and a front-end in Flex. The reason is that we have many ready-to-use Flex components that would take too much time to re-implement using pure web technologies, but here's not my point.
Creating a REST back-end in Grails is quick, as views are scaffolded when appropriate, controllers are straightforward, and input validation is greatly simplified by Domain constraints.
The drawback of this split is that definition of domain objects have to be duplicated in the front-end. You might includes objects validation in the front-end or not, but if you omit them, it will have an influence on UI responsiveness (requests to the REST back-end in AJAX calls for real-time validation to get the errors). At the end, our application is quite cumbersome because modifying objects in the back-end implies modification in the front-end. Furthermore, we do validation in both the front-end AND the back-end, and this code is not shared, so it must stay in phase and maintained at two places.
Our applications are split in a way that's similar to two completely distinct Grails applications that would share no code. A solution that would work in your case but is not what you are looking for, for sure.
In your case, I see two viable solutions for the web front-end:
use the Groovy REST client library to fetch and send back your domain objects directly from your controller. If needed, pack them in command objects that reflect your domain objects, so that you can share validation code with the back-end.
create some kind of REST GORM that replaces Hibernate with queries to your REST web service. You could look at the GORM for Mongo Plugin as an example of how to create such a GORM replacement.
I like the last idea, it would be a useful public plug-in. It doesn't exist yet, unfortunetly.

Componentizing complex functionality in an MVC web app

This is question about MVC web-app architecture, and how it can be extended
to handle componentizing moderately complex units of functionality.
I have an MVC style web-app with a customer facing credit card charge page.
I've been asked to allow the admins to enter credit card payments as well,
for times when credit cards are taken over the phone.
The customer facing credit card charge section of the website is currently
it's own controller, with approximately 3 pages and a login. That controller
is responsible for:
Customer login credential authentication
Credit card data collection
Calling a library to do the actual charge.
reporting the results to the user.
I would like to extract the card data collection pages into a component of
some kind so that I can easily reuse the code on the admin side of the app.
Right now my components are limited to single "view" pages with PHP style
embedded Perl code.
This is a simple, custom MVC framework written in Perl. Right now, controllers
are called directly from the framework to service web requests. My idea is to
allow controllers to be called from other controllers, so that I can componentize
more complex functionality.
For simplicity I think I prefer composition over inheritance, even though it will
require writing a bunch of pass-through methods (actions). Being Perl, I could in
theory do multiple inheritance.
I'm wondering if anyone with experience in other MVC web frameworks can comment
on how this sort of thing is usually done.
Thank you.
Create a component (class?) which wraps all the cc specific functionality, and expose it through appropriate methods/functions.
Use composition to provide your controllers, both customer and admin facing, an instance of the cc component, and have both call the appropriate methods to achieve what needs to happen.
I have dealt with something similar many times, and I absolutely prefer keeping my "controllers" (or any other code that depends directly on third party libraries for that matter) as "stupid" as possible, and do like you said - pass through anything that calls for functionality that's specific to your app. This keeps my code easy to test, which is what drives most of my design these days.
I hope we're talking about the same things, MVC can be applied at so many different levels it sometimes gets confusing.