Hexagonal Architecture and the Netflix Use Case (Part 2)
Check out part 1 here
The Netflix Use Case:
Netflix is multi-billion dollar technology and media company, providing an entertainment subscription service with nearly 200 million subscribers [1]. In recent years, Netflix has also expanded to produce its own movie/series in its ecosystem, called Netflix Original. Such an expansion has required the Netflix Engineering Organization to develop numerous applications to assist Netflix Original productions, from pitch to playbacks.
Problem:
In 2019, the Studio Workflow team started working on an application that will operate across multiple domains of the Netflix Business. At first, Netflix used a monolith system (one data system that stores multiple types of data at once). However, the growing business requires the monolith system to be broken down into multiple systems, distributing to multiple data sources (microservices). The idea is to set boundaries to the data, categorizing them to different domains so that dedicated teams can develop domain-specific service independently. With the change notified, the Studio Workflow team knew that they needed to be ready to swap the monolith data source to new microservices as soon as they come online, while not affecting the core business logic of the application.
Solution:
The principle of Hexagonal Architecture (as discussed above) is to (1) separate the core business logic from the dependencies (Transport Layer and Data Sources) so that (2) while the UI and Data Sources changes (or in this case, swappable), the data sent to Business Logic stays the same and the Business Logic is unaffected by these changes.
Recognizing how Hexagonal Architecture could solve their problems of swapping data source, the Studio Workflow team integrated the Hexagonal Architecture by separating the Business Logic from the dependencies as follow:
- Business Logic: There are three main components for the app’s Business Logic
- Entities: domain objects such as Movies, Users, Shootings.
- Repositories: interfaces to communicate with the data sources to create, change, and update entities. Usually, communication involves the data sources return one or a list of Entities
- Interactors (applications): responsible for performing business-logic actions, with complex business rules toward a specific domain
- Transport Layer: The layer responsible for sending requests to the business logic to handle a domain-specific task. This is usually referred to as the input of the system and usually triggered by the HTTP API layer, which handles the requests from the user.
- Data Sources: Adapter to different storages implementations
With the new implementations, it doesn’t matter which data sources the main entity is drawing from. As long as with each data sources, there is an adapter that performs the actions required by the port (interface) and returns the entities needed by the business logic, the application will run normally as though there have been no changes in the data sources.
Use case:
Back to the case of the Studio Workflow team.
Shortly after having integrated Hexagonal Architecture to their application, The Studio Workflow team encountered their first data source swap. While drawing entities from the monolith, the team encountered a read constraint while using JSON API and was required to switch to drawing the entities from GraphQL, where the read constraints are no longer a problem. The data stored in both data sources were in sync and drawing from either of the sources would have resulted in the same return of entities. As a result of swapping data sources, the team managed to implement and transfer data source reads from JSON API to GraphQL in a relatively short time (only 2 hours). The reason for this is that the business logic does not depend on the data sources. Therefore, the team only needed to implement an adapter for the new microservice (GraphQL) and attach it to the port of the business logic. The application worked as expected since no changes to the business core are changed.
My opinion:
- This is a classic case of using Hexagonal Architecture. When an application involves multiple user-side/server-side interaction but serves the main purpose (for example multiple platforms for front-end, and multiple data sources for back-end), it is important to separate the business logic from these dependencies and create a port-and-adapter architecture for the UI/data source to interact, but not disrupt/change the core domain of the business logic.
- The use case also touches a bit on Domain-Driven Design, created by Eric Evans. By separating the Business Logic into Repositories, Entities, and Applications, it seems like the application is modeled by incorporating Hexagonal Architecture with the Domain following Domain-Driven Design. You can read more about DDD here:
Sources:
[1]: Lee, E. (2020, April 21). Everyone You Know Just Signed Up for Netflix. Retrieved October 07, 2020, from https://www.nytimes.com/2020/04/21/business/media/netflix-q1-2020-earnings-nflx.html
[2]: Damir, S., & Sergii, M. (2020, March 11). Ready for changes with Hexagonal Architecture. Retrieved October 07, 2020, from https://netflixtechblog.com/ready-for-changes-with-hexagonal-architecture-b315ec967749