Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practices for shared constants between server and client using Backbone.JS

What is the best way to handle shared constants between server code and client code using Backbone.JS ? For example, say I have this map of user roles:

user_roles = {
  1 => "member", 
  2 => "moderator", 
  3 => "admin"}

Obviously, if you duplicate these definitions in code at both client and server side, this doesn't scale well and is error-prone.

The solution I could come up with is simply expose these definitions as a Backbone.Collection or Backbone.Model and fetch them from the server, but this might cause undesired overhead if you have a large amount of constant types, and I'm not sure whether they actually belong inside the model at all.

What are the different solutions to solve this problem, and how well do they scale?

like image 973
Leon Mergen Avatar asked Jan 06 '13 21:01

Leon Mergen


1 Answers

I've tried a couple of different ways of handling this issue. I don't know if either of them is the best way, but both have worked well for me, so I'll just describe them here and hope they're of help.

The core concept is the same in both: Constants are defined as true constants in the server-side language (C# and Java in my case), and are converted to JSON or javascript for the benefit of the client. I think this is the way to go, as opposed to sharing a single JSON/YML/etc. configuration file. Just because javascript doesn't have true constants doesn't mean your server shouldn't have them either.

Option 1: Load constants and enumerations in runtime via web service call.

Create a service endpoint (let's call it /enums) that basically collects all the server-side enumerations and constants into one big clump of JSON. To avoid an extra service call, if you're also using some server-side templating framework, you can bootstrap this into your index.html.

If you don't want to bootstrap anything to your static content, there are other optimizations you can do. Because constants change so rarely, you can wrap /enums response into a wrapper object that includes the server application build version. For example:

{
  "version": "1.2.1.0",
  "enums": { ... }
}

When the user hits the page for the first time, request GET /enums, and store the whole response into browser's local storage. On subsequent visits read the constants from the local storage and request the constants with GET /enums?v=1.2.1.0. The server should compare it's version to the passed version, and if they were identical, it would only return HTTP 200 OK to indicate to the client that its enumerations were still valid.

This option is good if you work in a distributed environment where frontend- and backend-developers are using different tools, or don't generally work closely together.

Option 2: Share constants as a part of a build process

You can use text transformation templates (such as T4) to generate javascript code from server side language source. In my case this was C#.

I stored all server-side enumerations in one directory and ran a build task which transformed all C# source files in that directory into javascript objects and combined them into one file enums.js in the client side source tree.

I found this to be a preferrable option, but if the client and server development is not done synchronously (built together, released together), the dependency management can get pretty messy. In my case I always deployed both client and server together, so this worked out great.

like image 194
jevakallio Avatar answered Sep 28 '22 04:09

jevakallio