This guide covers the core concepts of any Moleculer application.
A node is a simple OS process running on a local or external network. A single instance of a node can host one or many services.
Two (or more) services running on a single node are considered local services. They share hardware resources and use local bus to communicate with each other, no network latency (transporter is not used).
Services distributed across multiple nodes are considered remote. In this case, the communication is done via transporter.
Service Broker is the heart of Moleculer. It is responsible for management and communication between services (local and remote). Each node must have an instance of Service Broker.
Transporter is a communication bus that services use to exchange messages. It transfers events, requests and responses.
API Gateway exposes Moleculer services to end-users. The gateway is a regular Moleculer service running a (HTTP, WebSockets, etc.) server. It handles the incoming requests, maps them into service calls, and then returns appropriate responses.
There’s nothing better than an example to see how all these concepts fit together. So let’s consider a hypothetical online store that only lists its products. It doesn’t actually sell anything online.
From the architectural point-of-view the online store can be seen as a composition of 2 independent services: the
products service and the
gateway service. The first one is responsible for storage and management of the products while the second simply receives user´s requests and conveys them to the
Now let’s take a look at how this hypothetical store can be created with Moleculer.
To ensure that our system is resilient to failures we will run the
products and the
gateway services in dedicated nodes (
node-2). If you recall, running services at dedicated nodes means that the transporter module is required for inter services communication. Most of the transporters supported by Moleculer rely on a message broker for inter services communication, so we’re going to need one up and running. Overall, the internal architecture of our store is represented in the figure below.
Now, assuming that our services are up and running, the online store can serve user’s requests. So let’s see what actually happens with a request to list all available products. First, the request (
GET /products) is received by the HTTP server running at
node-1. The incoming request is simply passed from the HTTP server to the gateway service that does all the processing and mapping. In this case in particular, the user´s request is mapped into a
listProducts action of the
products service. Next, the request is passed to the broker, which checks whether the
products service is a local or a remote service. In this case, the
products service is remote so the broker needs to use the transporter module to deliver the request. The transporter simply grabs the request and sends it through the communication bus. Since both nodes (
node-2) are connected to the same communication bus (message broker), the request is successfully delivered to the
node-2. Upon reception, the broker of
node-2 will parse the incoming request and forward it to the
products service. Finally, the
products service invokes the
listProducts action and returns the list of all available products. The response is simply forwarded back to the end-user.
Flow of user’s request
All the details that we’ve just seen might seem scary and complicated but you don’t need to be afraid. Moleculer does all the heavy lifting for you! You (the developer) only need to focus on the application logic. Take a look at the actual implementation of our online store.
Now that we’ve defined the architecture of our shop, let’s implement it. We’re going to use NATS, an open source messaging system, as a communication bus. So go ahead and get the latest version of NATS Server. Run it with the default settings. You should get the following message:
 2016/10/31 13:13:40.732616 [INF] Starting nats-server version 0.9.4
Next, create a new directory for our application, create a new
package.json and install the dependencies. We´re going to use
moleculer to create our services,
moleculer-web as the HTTP gateway and
nats for communication. In the end your
package.json should look like this:
Finally, we need to configure the brokers and create our services. So let’s create a new file (
index.js) and do it:
node index.js in your terminal and open the link
http://localhost:3000/products. You should get the following response:
With just a couple dozen of lines of code we’ve created 2 isolated services capable of serving user’s requests and list the products. Moreover, our services can be easily scaled to become resilient and fault-tolerant. Impressive, right?