MVC , ReST, SOA , functional programming – all together!

Introduction

Raghav Chandra
Urban Company – Engineering
6 min readMar 6, 2017

--

Here are a few buzzwords. I will talk about them in brief and link it to the journey and use cases.

As software engineers, we work in teams and are most often working on code that is drafted by another team mate. We end up taking days to understand the code, the logic flow, the dependencies, the constraints, the corner-cases – only to make a few hours worth of changes. The difference between teams with good and quick iteration cycles vs lethargic code bases is the quality of code written.

Startups go through various phases of scale, and hence the segmentation of legacy code are of varying quality and style. Its important to constantly re-look at what is written. There is another post which talks about the code itself, here I will simply cover the architectural journey and how / where these buzzwords come in.

MVC, REST, SOA – all together!

Lets take an example of a simple application — retrieve data from a database and show it on a web page.

This requires a data base (store), some code to read and manipulate the data to prepare it for presentation (controller) and the web-page code itself to display that data (view). This is quite simply the Model-View-Controller way of architecting. The model has a controller layer which serves data to the visual view layer.

Now, as this system grows, lets say you add an Android App as a client. You also want to edit/update along with get. This now requires you to explicitly decouple your server code from the ‘client’ code. You will need an API to interact with the data in a state-less, client-server protocol, probably over HTTP. The model is still exposed via a controller, but the controller is evolved into being a ReST-ful API exposed over HTTP for server-to-client.

Fast forward, you have multiple database models, views are getting complex with multiple data models getting pulled. This is the right time to relook at how the system has been designed. Instead of exposing models via controllers, you start to encapsulate the ‘purpose’ as a Service. A logical service here retrieves the data to provide useful service regardless of the underlying data store. This service exposes the data to other systems, where a client can be a system itself. The service itself is now exposed using ReST-ful architecture over HTTP for system-to-system communication. The ‘model’ of different data units becomes redundant / useless / incidental at the service level. This evolution is into that of a Service-Oriented-Architecture.

The client now, has been exposing the data directly. To better architecture this data-to-view architecture, we would start modelling the incoming data, maybe even storing or caching it. This is where MVC gets used on the client itself. The client stores things as models, using a controller to be the middle manipulation layer to push / pull data from the view. Over time, even this becomes complex enough to go through the above journey, where client starts having a service instead of directly dealing with models, and using controller-for-services to talk and display data to the visual layer.

Now, before we go deeper with functional programming, lets understand some context behind it.

What are Programming Paradigms?

Programming paradigms are a –

  • “way” of programming and structuring code
  • “how” you write code
  • they are NOT mutually exclusive to each other
  • languages DONT have paradigms
  • languages might / might-not make it easy to write in some paradigms

Each paradigm gives a flavour that optimises for –

  • style and syntax
  • code organisation and grouping
  • execution model (side effects, parallelism, etc)
  • sequence of operations and triggers

Popular Programming Paradigms

  • Imperative — “how” the computation takes place step-by-step, explicit control flow, go-to’s, side-effects caused by global state manipulation
  • Imperative > Structured — introduces more logical program structure, loops, conditions, indentation (eg. using FOR loop instead of GOTOs)
  • Imperative > Structured > Procedural — introduces more modular programming by using local variables, functions to group code (eg. using a function to abstract code)
  • Declarative — “what” the result is, implicit control flow, no loops, no assignments, stateless, output depends on input, order of execution (the “how”) is not the focus
  • Declarative > Logic — facts, rules and goals, program infers the results, backtracking to find solutions (eg. Prolog as a language is purely declarative and logic/constraint driven)
  • Declarative > Object oriented — objects have state within them, stateless between objects, inheritance, encapsulation, polymorphism
  • Declarative > Event driven — asynchronous, control flow triggered by actions/events
  • Declarative > Functional — similar to mathematical functions, abstracting logic as independent functions, no shared state (no side-effect), no mutable data, control flow expressed by combining functions instead of assigning values to variables, composition of functions — chain and combine, allows parallelism of computation

Example (structured) –

var income_m = 0, income_f = 0;
for (var i = 0; i < income_list.length; i++) {
if (income_list[i].gender == ‘M’)
income_m += income_list[i].income;
else
income_f += income_list[i].income;
}

Note:

  • explicit use of variables that will contain the state of running totals;
  • explicit loop over the data, modifying the variable and hence the state;
  • conditionals to choose the code path at each iteration.

Example (declarative) –

select gender, sum(income)
from income_list
group by gender;

Note:

  • memory cells to contain running totals are implied by the output you declare you want;
  • any loop the CPU will need to perform (eg. over the income_list table) is implied by the output you declare you want and by the structure of the source data;
  • conditionals (eg. case in SQL) are used in a functional way to specify the output value you want based on the input values, not to choose a code path.

Good articles to read –
http://cs.lmu.edu/~ray/notes/paradigms/
https://en.wikipedia.org/wiki/Programming_paradigm

How should WE paradigm?

These paradigms are not mutually exclusive. You will find yourself using principles from multiple paradigms at any given point.

Procedural paradigm is useful at the bottom / unit / low level. You’d rather use it when describing a basic code block since its the most expanded / obvious way the logic would work and the execution order is clear without over-killing on the structuring.

Declarative programming is more abstract and helps better structure the logic of complex and big applications. Its easier to see relationships and logic flow since the purpose is to abstract out the “how” to focus on the “what”.

Whenever we are modelling a stated-system, or a mapping, we make use of the principles of event-based paradigm. eg: switch statements, state machines

Functional paradigm is a great way to structure code as independent, purpose-defined code blocks. By reducing dependencies on global variables / states, and allowing for functions to chain and compose together, one is able to write bug free and modularised code. This helps in building services and helps testing at the function / purpose level.

Sometimes, you want to model a service / object / user for which you might find it convenient to have states and inter-connected functionality. This is when object-oriented paradigm comes handy.

Hence, you could be modelling a system / service in an OOP, writing the code blocks there in a FP and utilising PP to write functions and code blocks. Or maybe create a large event-driven system that in its definition is the EBP.

Good articles to read –
http://www.redotheweb.com/2015/09/18/declarative-imperative-js.html
https://teamtreehouse.com/community/imperative-vs-declarative
http://www.perlmonks.org/?node_id=983655

Conclusion :

We spend hours understand the code compared to actual changes

We need to leverage SOA (similar to OOP at some level) to talk in Services

The code complexity and dealing with biz-logic is where breakage happens

This is because we write too much of Procedural code

We need to leverage Functional programming for code structuring

--

--

Raghav Chandra
Urban Company – Engineering

co-founder @urbancompany_UC ( previously, @urbanclap ). engineer. ex @twitter @cal .