Backend is important, it’s just the last of components

This post belongs to a broader mini-series on how we do Single Page Apps. So I advice to have a quick look there to know context a bit

Let’s recall why backend is important?

  • backend serves persistence, so all your data changes are stored safely, and you can go back to it any time
  • backend often is the guardian-of-the-secrets between frontend and external services like Facebook API, Pusher API. We do not want to publish secret API keys to the Pusher (realtime websocket communication) to anyone with View HTML Source power
  • in times where browser is the VM and console.log is available to everyone, backend validates user actions in environment isolated from end-user
  • backend used to contain application business logic that was meant to be reusable by different views (desktop, mobile, REST APIs, …), but failed to deliver in understandable way
  • it’s the place for fancy tricks to optimize resources usage and allowing service to run fast and failure free

So why would anyone want to skip backend in order to do what ..?

Well, it happens there are many cool things we can gain by treating the backend as just another plugin to our overall architecture and infrastructure. When we start thinking about it as an optional component many new ideas raise

  • first of all, in times when even-my-wife-can-code (RailsGirls) it is important (from a customer point of view) to get working software earlier. “Earlier” – means to work in limited time on limited things; to prioritize features; to focus on customer oriented benefits. Which are: simplest, working software prototype
  • in times where we all fail to deliver software up to the initial spec it is important to get customer feedback as early as we can. We achieve that by doing MVP products with most valuable, but minimal enough set of features. So we need to skip some parts first. What to skip?
  • time is money, losing time is losing money. Why would we develop things in areas of backend, persistence, load balancing, etc.. when nowadays products often change, pivot or are even abandoned if it’s a better option
  • it looks OK to deliver what customer wants, but it’s lot cooler to deliver what customer needs!
    What does customer need? I suppose often he/she doesn’t know. It’s fine. It is also our (devs) responsibility to work with the customer and advice on solutions, ideas, possibilities, alternatives. To propose and educate the customer within product scope. But how customer can know if what he wants is what he/she needs? Let’s validate the product. Does the product make sense at all? So let’s develop early a functional product that we can use and work
  • we cooperate with many developers and not everybody knows the Rails stack. It appears it’s not so easy for a newbie to install MySQL, Rails, irb, bundle, rvm, compile gems, watch Coffee to JS, etc..
    Why should devs struggle with it when it’s possible to just to run static index.html in the browser? Why should a developer start with infrastructure problems if they can start with solving customer problems first?

One conclusion from above is we may skip software parts not essential to a customer

In order to have a working app:

  • we cannot skip the view – we need to show, use, click in the app. So this part is essential
  • we cannot skip the domain. We have to understand and code underlying business and processes of the customer. So business domain is – again – essential
  • it’s the browser world, so the frontend, JavaScript code is a must. Better to have code (html, JS, css) natively in the browser, than to generate and concatenate it via a MVC framework

The parts that we can can skip and we do are:

  • persistence in database on the server side
    Each of our apps first has a persistence limited to current user session. With ability to provide different data states initially we’re able to play different game/app scenarios
  • routes
    As there is no backend, nothing to route. Our frontend code talks to middle layer first, a thing called “server side adapter”. Only production server side adapter talks to URLs. Initial in-memory-adapter talks to simple plain old JS example objects
  • controllers
    As we develop domain logic inside usecases, and they drive the behaviours and use cases and the glue connects different layers/services, there is no need for this structure. Or at least it looks different.

How we achieve it?

  • having server side adapters for communication from frontend to backend.
    We tend to have 2: in-memory-adapter, that is violatile and with CTRL+R will start fresh set of data. But also starts with predefined set of data. Easily configurable. Running in browser only. In plain, old JS variables, arrays, hashes.
    And real server-side-adapter (production ready) where full blown implementation is delivered. It connects to backend via Ajax calls to server url resources.
    Both share same API. It’s just that in-memory is being delivered first and needs almost zero programming efforts
  • separating domain and view completely. They don’t know each other. This separation gives better understanding of the domain in early stages. And allows to modify it more freely.
    Independent view is easier to be delivered earlier. View developers have its API defined clearly and can focus in these areas only. We can also replace view implementations in the whole system with little efforts (let it be DOM/CSS implementation or Canvas)
  • “unit” testing of domain from command line.
    For JS/Coffee code we use Mocha or Jasmine. The former one allows to write test-first within the first hour of the project
  • in multiplayer games we tend to load domain multiple times and simulate multiplayer locally in the browser.
    It’s lot of fun and effective and a mind-opener

Do we need persistence or any external services implemented at the stage of demonstrating a working app to the customer: sure not … yet!

 

Backends as you know it are gone. Gone forever. Think end-users and elegant layering

This post belongs to a broader mini-series on how we do Single Page Apps. So I advice to have a quick look there to know context a bit

You sure do remember days of starting new project with coolest, modern MVC framework in your favourite language, and picking your favourite ORM you could die for evangelizing, and hating all other database systems that are different than the one you worship?

Well, you are wrong then. .. So did I.

We must remember, it all ends up with an app that user uses via browser and gives a fuck to all the technology we use underneath.

Users want a working thing (a game, an app, a website, a crm, intranet app, you name it..) that is:

  • responsive (aka Single Page Application)
  • does what they need (aka early prototyping, and having short feedback loop)
  • they can change it (aka change of requirements)
  • error free (aka show me your code)
  • error free (aka maintainable)
  • multiplatform (aka shared codebase)

I coded few years here and there, being Java fanboy, Python, bit of Ruby, all the time doing some shitty Javascripts and always trying to hide SQL complexity behind orms (Hibernate, SQLAlchemy, AR) for mysql, postgresql and bit of mongo and sci-fi prevalence.

But – always trying to write readable backend code.

I end up today writing FRONTENDS, SPAs, javascripts, usecases, roles, with no evil inheritance, no orms, little code reusing, but finally having code that matters, that shows real purpose and is read well, and does what it should.

Some of you may have already read Uncle Bob’s Clean Architecture blog post on separating layers.

You’ll find similarities in GameBoxed styled architecture on how we do it.

In the system core there are usecases.
Usecases are the behaviour and are pure. Plain, old, Javascript objects. No db, no ajax, just plain classes, simple data structures, nothing persisted! (later on that..)

There can be many usecases, implementing some fraction of business domain. They will mostly use rather dumb objects (you could say your model).
When you look there, you should see clearly what is the app purpose and behaviour, flow of user scenarios.

So let’s jump straight to our code, and see for ourselves.

To repeat: pure domain. You can test it in command line. You can run it in the browser environment. You could run it in any backend supporting JS if you’d like.

Give it some input (load data), use it and work with its output. May be as the BLACK BOX for you.

Usecases have three types of methods

  • Input: entry points to accept end-user requests (we name them with words from business domain, but these requests come from naive clicks, or text inputs, or finger swipes, or whatever else a user can do to our app) “playerFinishedTutorial()”
  • Output: empty methods that are results of some important logic happened. You can think of it as events too. “readyToStart(), nextSecondElapsed(), playerGotPoints()”
  • private methods of a usecase

Let’s see one that requests something from a usecase. A simple one this time:

Data of a usecase lives in browser’s memory. It’s a live data structure (a state machine one could say) that changes only because of a user request, or when some time countdown completes. So when it changes, it communicates it … ehmm.. on itself (you’ll see why later)

No domain method knows about view, nor communicates with it directly!.

To connect output of a usecase to external services, view, sounds we are applying a thing called “glue”.

We glue 2 layers together: domain and view. In both directions. It’s thin layer! Knows how to pass parameters. We do it with simple AOP.

This way an internal layer (domain) can engage and pass the “message” to outer layer (a view, a sound subsystem, a social platform, a REST api, whatever)..
And vice versa. If end-user needs to interact with an app, then glue passes message from view (clicks) down to domain via input methods.

See it in action: a glue for web DOM representation of a domain. (we do have different glue for playing sounds, or talking to Facebook social platform)

And to have complete picture of what we call view layer, let’s see view:

How persistence is handled? Might be this way:

Now, these are the basics! Knowing that let’s move on further!

We do start with a browser. We code in the browser. We separate code into clean layers. View knows nothing about domain and domain knows nothing about MANY services that use it.

Glue (many glues) ties together these layers.

Domain tests can be written in command line. Domain is written as the first one. With it being clean we achieve simplicity and less bugs if any. As it is often written in same words a human would describe a business process in more or less “programming English”.

Having it AND NOT WORRYING about persistence, not worrying about backend!, we can provide early, working in the browser prototype of the software. This can be shown to end user and validated and again modified, and… again.

This way of working has been verified and used through several of our apps. We have games too. Games that players play and have fun. And developers have fun too.

What about backend? It’s a browser. So user can do whatever can to hack Javascript and run own code (aka console). And we’d love not to duplicate business logic on backend too :-}
There are at least 2 realities. And any way, backend is just a plugin to our overall architecture. Can be plugged in, or off.

  • we care about hacking via browser
  • we don’t care about hacking

Sometimes it’s just the surroundings of an app business, that we may allow mild hacking. If minor things happen, we just save developers time and $$$ and move on to the next project.
Or maybe it’s a safe intranet environment, where we can trust users? Or we can just trace their actions via logs. If that’s OK that’s great!

Sometimes though, we would be sorry if only frontend would drive backend persistence. And thus for example a HTML5 game player could influence his earned points, and made himself the one in top of hiscores. We’ve seen gamers with 999999999 points, haven’t we?

There are really 2 ways we can take:

  • we duplicate Javascript domain code into our fav backend platform (Ruby, Python, Java.. whatever)
    We know it’s caveats but that might be the only option. Not so bad, if done AFTER frontend is complete. As it’s just a rewrite + maintenance after (keeping code in sync)
  •  we reuse domain JS code in some backend that can run native JS. Node obviously. What else? JVM? Ruby? Tell me please.
    It’s not so easy for non-Node platforms, but can be done. And if the domain logic is heavy, then it just can make sense.

A word of advice. A browser is an ideal platform to do real Model-View-XXX strategy. It’s where your domain code will shine again. Stress free, elegant, and most important .. nothing new really.

You can always follow me on @nthx17. Further working ideas from space will come soon :-)