Tech Blog

Facebook Icon Twitter Icon Linkedin Icon

AnyMind Group

Facebook Icon Twitter Icon Linkedin Icon

[Tech Blog] Development of AnyLogi from scratch to today

Greetings, I am Shao Hong, the tech lead of AnyLogi product team. I am excited to share the release of AnyLogi and technical details in this article.

About AnyLogi

AnyLogi is a Logistics Management Platform for D2C Business, but what set us different is the capability of connecting and enabling merchants to overseas markets that was never thought to be as simple as going through a platform. With current and upcoming connections to different e-commerce platforms and warehouse management systems (WMS) spanning across Asia, any business can have their inventories located in regions supported by AnyLogi.

Design

Being the middleman between e-commerce platforms and WMS is not an easy task. Without proper domain and business boundary, it is easy to leak unnecessary implementations from one component to another. Therefore, the general idea is to treat any components as its own and never mix different components in the same codebase. This results in the following diagram, showing the boundary and relationship between the core domain of AnyLogi and the different components powering the entire system.

Tech stack

System architecture

We chose to have a API gateway early on in the development to ensure both Front-end and Back-end are not hindered by the contract of each team. Using an API gateway as a buffer, Front-end has full authority on the schema that they will consume, and same for Back-end to have the same level of authority on the schema they will produce. This also decouples the technology that both teams will be using.

Languages and frameworks

The front-end and back-end both uses different languages and technology best suited for the task and are as follows.

  • Front-end
    • Typescript
      • Angular
  • Back-end
    • Go
      • Echo
    • NodeJS
      • NestJS
      • KoaJS

Although there are already some language choices set in place, we are open to other languages such as (Java, Elixir, Rust, and etc.) to be a part of the ecosystem as long as we are able to utilise them fully to propel AnyLogi in beccoming a better, more stable, more scalable system.

Event driven architecture

AnyLogi consumes data from many sources, where each of them happens at a different rate. We implemented the system in an event driven way to ensure that it is easily scalable and not bottlenecked by any part of the system.

With event driven architecture in place, we opted for event sourcing in crucial parts of the system. Event sourcing is a kind of data state management technique which benefits most when a piece of information can have different state throughout its lifetime.

Example of a life cycle of an order

ORDER_CREATED
ORDER_UPDATED
ORDER_ACCEPTED
ORDER_PAID
ORDER_DELIVERY_INITIATED
ORDER_DELIVERED

Event sourcing focuses on events as its first class citizen where the event itself is the source of truth of a piece of data, rather than the conventional domain object or entity as the source of truth. By going through the events, we are able to build a copy of the domain object/entity (aggregate) for normal application use cases. This largely benefits those domains where the evolution of state is important.

Command Query Responsibility Separation (CQRS)

One downside of event sourcing is the lack of a ready-to-use database schema that can be used to perform queries. Due to the nature of event sourcing, playing though the events on every query is not a great idea as some aggregates can live for a long time. This becomes even worse when pagination is needed as we need to play through the whole event store just to show a few rows to the front-end.

Therefore, CQRS is used alongside with event sourcing to generate views on the fly. Once a new event is added into the event store, a worker will pick it up and update the corresponding view.

Business Challenges

Developing a system without the full picture on how the final product will look like in 3 to 5 years time is a difficult task. Different e-commerce platforms and warehouse management system have their own business logic and work flows that can be contradicting from one and another. The business flow can be easily influenced by the first few vendors that we integrate with, where all pros and cons of the vendor will be inherited into AnyLogi. From a short term perspective this would be beneficial as AnyLogi will be able to launch much earlier, however it will bite us back in the future when the downsides of the business flow prevents us from scaling larger and/or implement features that does not adhere to existing logic.

Therefore, before adopting any existing business logic from vendors, we need to thoroughly assess the possibility of it being different from another vendor. From this process, we sacrifice the current time allocated for development for a future where we can easily migrate from one vendor to another. In the long run, AnyLogi will have its own business rules and we will be able to manipulate the usage of our vendors to fit our use case. From a DDD point of view, this makes knowledge transfer and onboarding easier as everything happens in the same way within AnyLogi.

One common example is the usage of status flags. As there are no de-facto rules or standards in this field, companies can create their own way of representing status. During development, we noticed that one of our vendor uses seven different variables to represent the status of an order, having more than 50 possible combinations that were discovered during our day to day operation. If we decided to use the same design within AnyLogi, it will be hard to translate statuses from one and another. It is also difficult to understand as we need to memorise every one of the different combinations and their effect on the order. To combat this problem, we devised a simplified version of status that contains only two different variables, bringing down the combinations to just 11. No matter how different the status are from different vendors, we would map them our own statuses and therefore removing the need for us to remember a whole new set of statuses.

Conclusion

When developing a new system with an optimistic exponential business projection, we should lay the fundamentals since day 1 to ensure that we are able to scale easily later on. It also makes sense to slow down the urge to release an MVP and focus on how the product will look like in the long run. I hope this article helps everyone who are starting a new product no matter in an existing market or an untapped market.

Thank you for reading.

AnyMind tech team will keep developing new products and update our technology stacks based on business requirements.

If you’re interested in our product development team, please select “Product Development” from the link below to see open positions.

Career | AnyMind Group

We also have a blog written by engineers in AnyMind Group. If you’d like to read it, please click the links below:

Latest News