Benefits of extending commerce via API over plugins
Overview of extensibility architectures and benefits of APIs over plugins.
Plugins and APIs are the most common approaches to extending eCommerce platforms. They share a common goal of extensibility, but the developer experience between them is markedly different. For that reason, extensibility architectures are one of the most discussed topics when selecting an eCommerce platform.
Like many open-source projects, the initial design of Saleor was based on a plugin architecture. However, in 2018, our team and community recognized the benefits of an API approach and rewrote Saleor to use GraphQL-based extensibility.
This article, will cover the main differences between plugin-based and plugin-free models. As the core principles are universal, this knowledge both sheds light on Saleor’s evolution and, more generally, makes clear the benefits and drawbacks of the two models.
Plugin architecture (aka monolith)
Plugins are extensions of an application’s core logic. They follow a specific interface or protocol to extend the platform’s behavior. A typical plugin, or “extension,” has a configuration file and other files containing classes overriding a default behavior and that behavior’s dependencies.
Plugins are just extensions of the core files and so they must have access to some of the dependencies and databases. The interaction between core and plugin is governed by an SDK or specific protocol, creating a tight coupling in the following form:
- Plugins run in the same runtime and environment as the core, sharing resources such as memory, CPU, and the database.
- Core and plugins have to be deployed together.
- Plugins rely on specific versions of the core and sometimes on other plugins, creating hard-to-manage cross-dependencies.
- Database migrations are performed on the same database instance as the core.
- Not trivial to pinpoint whether crashes, errors, and consumed resources stem from plugins or core.
- Hard to properly sandbox the plugin and prevent it from interacting with the unintended parts of the codebase
In some SaaS vendors, plugins are more restrictive and isolated from the core, which mitigates some of the issues described above but platform might impose limitations on plugins, such as:
- Memory allocation and stack memory limits
- Prohibit external network requests
- Input and output bandwidth limits
- Non deterministic output which doesn’t allow use of clock and random functions
Why plugins are popular?
Although some platforms (including Saleor) have moved away from plugin architectures in favor of an API-based approach, plugins are still widely used. The reason is there are some clear advantages for both platform vendors and users.
- Portability of plugins simplifies the process of distribution, which creates an opportunity for marketplace creation and an open-source ecosystem.
- Developers without backend experience can be trained to build on top of the platform.
- Building plugins is specialized knowledge, which creates community of experts that can be certified.
- Portability simplifies project handover for freelancers and agencies.
- The plugin architecture does not require a backend setup, which makes it faster to get started. (This is debatable. Modern serverless services make API-first development more convenient in many cases, hence it is now more of a matter of developer preference or mental model.)
- Platforms can avoid having to design and implement a public API.
- Removes issue of limited availability (if the platform is there, the plugin is also there, since they are part of the same process)
API-first approach
API-first means all interactions are made over HTTP. In the case of Saleor, that’s a GraphQL API and with others it may be REST. There are three different ways to extend functionality of the platform:
- Direct API calls for CRUD operations. These typically fall under two categories:
- Public calls: interactions with a catalog or checkout performed by a storefront.
- Authorized calls: interactions via backend with privileged access token that allows to read private data or create writes.
- Async webhook events notify about events happening in the system such as order creation, product updates, etc.
- Sync events expect a reply from the external system. Let’s take bespoke shipping cost calculation as an example. A user adds an item to a cart. Before returning the price of the cart, the commerce engine calls an external service to obtain a shipping price. The external service returns the price, which is finally presented in the shopper’s cart.
In contrast to plugins, any service can be used to extend default platform behavior, which means freedom to locate business logic where it is most suitable. Here are some ways one might distribute such logic:
- Microservices. Create independent services for cart, inventory, customer, search, and personalization. This allows for each service to be developed, deployed, and scaled independently.
- Backend for front-end. Backend logic can be located in front-end application making it portable and agile.
- Cron jobs, serverless functions, or marketing automation scripts.
Such approaches make it possible to centralize or decentralize the business logic in the optimal way. For example, when building a proof of concept or simple storefront one might find it convenient to directly call backend functions from a front-end framework like Next.js. On the other hand, a complex, production-grade enterprise project might opt for a dedicated service that may be consumed by mobile, web and back office applications. In other words, users have governance over their business logic and the complexity of their architectures and technologies.
While the above benefits of API approach mitigate many drawbacks of plugins there are few trade-offs worth noting:
- Authorization and token management is required.
- Critical business logic needs to be located close to cloud services of the commerce platform to ensure performance.
- Distributed business logic requires monitoring and an observability setup.
Advantages of API over plugins
Plugins have been around for decades while practices have evolved and iterated around them. There are successful, large-scale stores running on plugin-based platforms, but there are many problems inherent to the design of this architecture. Technology-agnostic, API-first platforms eliminate many of the problems:
- No technology lock-in. Plugins architecture dictate underlying technology choices such as programming language, runtime, database, workers, etc. This limits ability of the team to experiment or adopt different technologies.
- Scaling and performance. Independent services for extensions gives more control over performance and costs.
- Debugging and observability. With an API approach you are in control of your service giving you more visibility and debugging options.
- No platform lock-in. Let say you built custom price calculation service as plugin, it would be difficult to adopt it to another commerce platform compared to a standalone microservice.
- Larger talent pool. Plugins require specialized knowledge of the platform, its programming language, and stack. With an API-first approach, your data science, backend, and frontend teams can each build with their preferred technologies. The teams may develop in parallel and hire without concern for platform experience.
- Deployment. Plugins require redeployment of the platform which can introduce undesired downtime and slow development velocity. In contrast, the API approach, especially with serverless deployments, is a seamless process of preview environments, progressive rollouts, and zero downtime.
- Stopping crack propagation. Sharing infrastructure with your commerce platform makes it more fragile, specially on high velocity projects with frequent deployment.
- Independent ownership. An API-approach may be used to create isolated microservices tailored to specific regions or business channels. For example, a cart validation service built for specific foreign markets or a payment service for a certain set of customers. These services may then evolve and be deployed without interfering with one another.
- Business logic placement. Commerce platforms interact with different business components. A common case is centralizing the business logic between the CMS and the eCommerce platform. An API-based approach covers the case, whereas a plugin-based approach would require two different deployment targets, one for each stack.
APIs are the present and future of extensibility.
Plugin architecture was a dominant style of commerce and CMS decade ago, specially popular among open source, however API architecture is now dominant form of extensibility be it marketing, payments, search and other business components that need to be composed together, which makes monolithic approach of plugins less practical. For any project that evolves developers it is crucial to evaluate the extensibility architecture of the platform as it can have big impact on the velocity of the project and costs.