Creating an ODM with JavaScript
I think the first time I heard about ORM was 10 years ago. I discovered this technique on a NetBeans tutorial that explained how to generate Java classes from a MySQL database. I made some tests and it worked pretty well. I really liked the concepts but not the execution. I was quite frustrated with the generation step because I had always to regenerate classes for every structure update of the database. This problem was in fact related to the language used for the mapping that needs to be compiled. I said to myself that it could be simpler to use a dynamic language that could generate these classes at runtime. That’s why I started at that time to create my own ORM with JavaScript. It worked quite well but I get stuck with a big limitation: MySQL. The relational structure of the tables did not match with JavaScript native objects. So the mapping was not as easy as I wanted.
But things changed a few years later when NoSQL databases became more and more popular. We could use pure JSON objects as documents and we could manage NoSQL data as native JavaScript objects.
I will show you in this post how it is easy to create now an ODM (Object-Document Mapping) with JavaScript.
My first ODM
Let’s start by choosing a NoSQL database. We will use my favorite one, I call it the universal database: {}.
It is light, can work on a server or on a browser. Everything I like!
Now that we have the database, let’s stop a minute to think about object creation in JavaScript. Generally we use many parameters to create an object, like this:
But we could also pass one object as parameter:
Did you notice that this parameter looks like a document? That is the main idea of ODM: use a document as a parameter of the class constructor.
Now we have that in mind, let’s create the class that will manage the mapping between documents and class instances:
In this class we made several things:
- we get the name of the collection in the database: in our case the class name,
- we generate a unique id for the document,
- we add the document in the database and
- we create getter and setter for every property of the instance that will manage the related document in the database.
Now let’s do some tests with it:
We have now a complete synchronization between documents and instances. And we did that with only 30 lines of code!
Documents exportation
Let go further. And if want to export documents? It is very easy to do that:
In our case we suppose that all the documents are JSON valid so that we can export them with a native JavaScript API.
Now let’s make some tests with it:
In this example we export all the documents created for a specific class. That means that we can now serialize all the objects into a string. Pretty cool, does it?
Documents importation
Now we will do something a little more complicated with the importation of documents. When we import documents on a specific collection, we want to create their related objects:
Now let’s update a bit the main class for that purpose:
The difference with the previous class is that we add now the created instance in the list instances.
Let ‘s test it:
We can now deserialize datas into objects. Moreover we can also know the exact number of created objects at any moments, it is the number of objects in my instances list.
Managing data relationships
And what about relations? In NoSQL world, we can simulate relations by using the id of a document as a value of a property to create a link. If we follow this pattern, managing relations becomes very simple:
To distinguish a value from a link, we add this new rule: if a value begins with @, it means that it represents the id of a document.
Let’s create now a link between objects:
Now, let’s do this link at API level:
As you see, we can create one-to-one relationship very easily with ODM.
Conclusion
ODM is a technique that you have to use more often in your code, it is not complicated and very powerful. Because of the heavy coupling between documents and objets, you know at every moments what are the components of your application, how many they are and what data they manage.
If you think harder, you realize that in fact ODM is a way to manage the store of your application. Every kind of components has its own store (i.e. collection in the database) and can be managed like in Redux. But here you are at the functional level (you manage functional objects), not at the technical level (where you manage data).
I made some CodePen examples so that you can start to play right now with ODM:
If you want to go deeper, you can have a look at System Runtime, a JavaScript library that I have created that applies all the pattern I talked about in this post.