Splitting Off One Part

We have split a system into services twice.

The first was the registrar’s system. The registrar’s application and the Public Courses API ran together on one server. The API’s traffic kept growing, while the registrar’s staff used the application at a steady pace. Each time we added an instance for the API, we also added a copy of the application, and the application’s own traffic did not need that copy. Also, when we fixed the application, we had to redeploy the API. So we made the API a service of its own. A gateway sends each request to the application or to the API by its path. Both read the same database.

The second was CodeDrill. One application served the problem pages, saved the submissions, and ran students’ code. The night before a midterm, the students’ code used up the cores that the pages needed, so the pages slowed down. So we moved running code into a service of its own. We called it the runner. The application calls the runner for each submission.

Recall that a service is a part of the system that can be run, deployed, and scaled on its own. In both systems, we found one responsibility that did not fit with the rest: serving the API, or running code. We gave that responsibility its own boundary.

Everything else stayed where it was. The registrar’s application is still one application that does all of the registrar’s own work. CodeDrill’s application still serves the pages, keeps the problems, and saves the submissions. Each system now uses a service, but its design is still one application with one part taken out.