B2B stores are a part of the eCommerce world that focuses heavily on optimizing business processes, reflected in the company’s growth.
The main B2B commerce characteristics are:
- big numbers related both to the number of products in the catalog and to the number of orders placed
- division into teams that are specialized in doing particular tasks
- implementing processes that aim to improve workflow between teams
Each company offering B2B Commerce services has its own set of procedures, which often go beyond standard eCommerce processes. Hence, there is a need to divide a monolithic application into smaller, more specialized units called microservices.
- Modularity of B2B Commerce domain
- Most common microservice messages in B2B Commerce
- Queue systems for microservices
- Queuing systems-how to start?
Modularity of B2B Commerce domain
In the B2B Commerce domain, business processes usually combine into larger modules despite their mentioned uniqueness. Each of them is responsible for a different part of the business, which directly translates into the order within the organization.
The most common modules used in B2B Commerce are:
eCommerce – an application responsible for sales processes of products
Product Information Management (PIM) – used for managing products’ catalogs, for example, adding product information that can be used by the sales system or defining the structure of categories available in the sales platform.
Enterprise Resource Planning (ERP) – module related to product files, sales information, and accounting.
Warehouse Management System (WMS) – as the name indicates, used for various warehouse processes.
Content Management System (CMS) – responsible for managing content that appears on the eCommerce platform.
The list of modules should also include external services that are integrated with the organization, such as delivery services. Each of the abovementioned modules usually exists as a separate application that only has access to information that is critical to its proper operation. Since the modules never use one shared database, there is a need for information exchange between each of them. Most often, this communication takes place by sending and responding to messages received from outside.
Most common microservice messages in B2B Commerce
Nonetheless, not every system must communicate with every other system available in the organization. Only systems that need to communicate with each other do it.
Now, let’s go through basic cases where an eCommerce tool could communicate with other modules, as in the graphic below:
1. PIM -> eCommerce
The PIM tool communicates with eCommerce, providing information about:
- Creating a new resource
- Modification of an existing resource
- Deleting a resource
As a resource, we should take not only products but also categories, tags, attributes, media, and other elements directly related to a presentation of the sales catalog.
2. eCommerce -> ERP
In this case, communication between ERP and eCommerce can be one-sided or two-sided. Depending on the processes within the organization, the ERP system can send messages to eCommerce or vice versa.
The most common case when the eCommerce platform will communicate with the ERP system will be information about a newly placed order. In addition to this, the eCommerce platform may also have to communicate with the ERP system when a customer files a complaint or return.
One of the basic messages sent from the ERP tool to the eCommerce module will be the issuance of billing documents, such as an invoice or correction, to which the customer will have access from his account in the sales platform. In addition, the ERP system may contact the store when new product files are created.
3. eCommerce <-> WMS
When we are talking about the warehouse, it usually is about getting information about new orders from eCommerce. Apart from that, WMS can also request information about returns and/or complaints, where a company can be obliged to send a new product to the customer.
The eCommerce platform, in turn, will surely be interested in information about the change in inventory. In the case when we have only one sales platform, this information seems to be redundant. However, it should be noted that B2B Commerce business often occurs on many channels and markets. Therefore, there is a need for stock change information received by the eCommerce platform.
Queue systems for microservices
In order to communicate, each module is in the form of a microservice, which can receive messages from another system. It is usually done by sending HTTP requests to a published API microservice.
Despite several advantages of communication via API, this solution has a rich set of problems:
1. Microservices expose APIs to the public. It is a very sensitive place, which, if inadequately secured, becomes an easy target for unauthorized people.
2. Potential performance issues when the temporary workload is too high.
3. The script execution timeouts imposed by the HTTP server can be an obstacle for messages that require a little more time to handle.
An alternative communication solution of microservices is using so-called queue systems, which create a bus between microservices to which messages are sent. Each of the microservices can connect to such a bus with the appropriate number of consuming processes, i.e., the ones that process messages.
Advantages of using queue systems:
1. The API is not exposed externally using the HTTP protocol. This gives you an extra layer of security.
2. A simpler way to distribute server resources in relation to the amount of data remaining to be processed.
3. No time limit for message processing.
Which queuing technologies to choose?
There is a lot of software that provides queue functions. They differ mainly in supported protocols, methods of message processing, or API. The most popular and, at the same time, very stable solutions are:
- Tools managed from a private server: RabbitMQ and Apache Kafka
- Cloud Tools: Amazon SQS / Google Cloud Pub/Sub
Referring to tools installed on private servers, there are numerous materials available on the network that explain how to install and then operate the technologies listed above. Examples of very good quality materials are instructions provided by DigitalOcean: How To Install Apache Kafka on Ubuntu 20.04 and How To Install and Manage RabbitMQ. Documentation of tools available from the cloud level can be found on the AWS – Basic Amazon SQS architecture and Google Cloud – Architectural overview of Pub/Sub websites.
Queuing systems – how to start?
Each of the technologies mentioned above has its own API, based on which we can create our own code. Thanks to such code, we will be able to communicate with the queue system.
There are many solutions available online that we can use:
- SDK tools listed on the official RabbitMQ website
- PHP extension called arnaud-lb/php-rdkafka
- Official SDK from AWS that gives you the ability to support Amazon SQS (examples here)
- Official SDK from Google for working with Google Cloud Pub/Sub
Each of these solutions is specialized to contact only one specific system. By using them, we get more or less attached to the infrastructure, making it difficult for ourselves to switch to another technology. This may be particularly problematic when we make the application logic dependent on how it communicates with the queue system.
Symfony Messenger and Enqueue Bundle
In the Symfony ecosystem, the technology from which Sylius originates, there is an ideal tool whose architecture based on the Command Bus pattern which allows you to work in a way that enables communication between microservices. This tool is called the Symfony Messenger component.
Working with the Symfony Messenger library involves creating messages, most commonly called commands, which are then dispatched to a command bus instance. Inside the command bus, such a message is processed by a finite number of middleware. Among the middleware, there is one that checks whether routing exists for the message, leading to an asynchronous bus on which scripts of another microservice are present. If such routing exists, the message goes to the queuing system on the bus, after which it is reprocessed asynchronously by the consuming scripts hooked up to it. In case routing is not configured, and there is a handler class assigned to this command in the dispatching system, it is reprocessed in a synchronous manner.
Using Symfony Messenger in the application brings a lot of advantages. The most important of them are the following:
- In a simple way, we can delegate synchronous processes in the so-called server background. We are able to achieve this mainly through configuration files.
- With a well-chosen abstraction, the code is more focused on the business logic of the application.
- Symfony Messenger makes it much easier to migrate to another queuing system.
Symfony Messenger itself does not have mechanisms that could send a message to the queue. To be able to achieve this goal, we would have to write our own transport. Fortunately, someone has already done it for us, creating a php-enqueue/enqueue-bundle. Thanks to this tool, we can switch between many different queuing systems in a very transparent way, including those mentioned in today’s blog.
Customized B2B eCommerce Solutions for Wholesalers, Distributors, and Manufacturers
Challenges to keep in mind
Working with queuing systems, regardless of whether it is to delegate tasks to the server background or to communication between microservices, leads to new problems that we can potentially deal with at work:
1. Shutting down a queue system can result in the loss of all messages that were held on all buses put on it. Fortunately, all of the queue systems mentioned in this post have an option for storing messages in the file system.
2. Heavy traffic can cause the effect of so-called starvation. It consists in the fact that some messages – due to their specific context – clog up consuming processes with long processing time. These types of situations should be analyzed, and messages of this particular kind should be sent to consuming scripts that will be intended exclusively for this purpose.
3. The other issue can be the parallel processing of messages that depend on one another. The simplest example is the execution of a creation message and a product update message on two free (at the current time) consuming scripts. Before the product is created, the message for its update will be processed. The simplest solution to this type of problem is to use a processing loop combined with placing the problematic message back at the end of the queue.