Two Systems, One Catalog
A student uses CourseTracker by first searching for a course they took, then adding it to their history. Chapter 2 gave CourseTracker that search requirement. It did not say where the catalog being searched comes from.
We do not want a student to type their own course information in by hand. That recreates the spreadsheet, the exact problem chapter 2 started by fixing. The search has to run against the university’s real catalog, kept by the people who actually run it: the registrar’s office, which assigns course numbers, schedules offerings, and knows who teaches what, because that is its job. When a student then adds one of those offerings to their history, CourseTracker needs the same real facts to go with it: title, credits, professor, meeting time, room.
CourseTracker does not need to hold the whole catalog itself to do that. Search can run directly against the registrar’s own data. When a student adds an offering to their history, CourseTracker records the offering’s details and related information (the course, the professor) in its own tables. The registrar’s data does not come back in the shape of CourseTracker’s tables. It comes back the way the registrar keeps it, and CourseTracker takes it apart into its own tables. If another student later adds the same offering, CourseTracker reuses the already-stored records. Every other read CourseTracker performs runs against its own tables.
So CourseTracker has to reach the registrar’s data in one place: when a student searches it. What comes back has to carry enough about each offering for CourseTracker to record the one the student picks. The obvious way is to connect CourseTracker directly to the registrar’s database. This does not work.
First, the registrar’s schema was built for the registrar’s own use, not as something another team can depend on. CourseTracker queries start returning the wrong thing if the registrar’s office renames a column, splits a table, or changes what a value means. Second, a direct connection risks exposing more of the registrar’s data than CourseTracker needs, rather than just the course catalog. This is a security concern. Third, if CourseTracker’s traffic spikes, whether from a bug or just because it got popular, it can overload the registrar’s database and slow down the registrar’s own work.
The same argument chapter 3 made about a deployment boundary applies to all three: two systems run by two different teams are supposed to be free to change independently of each other. A direct connection into another team’s tables removes that freedom. Every change either team makes now has to be checked against the other.
What CourseTracker actually needs is much narrower than a database connection: search the catalog and get back enough about each offering to record it. The registrar’s system could expose just that, over the network, in a form another program can connect to and use. That is an API (application programming interface): a defined way for one system to ask another to do something, whether that is returning data or carrying out an action, instead of reaching into how the other system works.
What if the registrar updates its catalog?
CourseTracker can use the same API to refresh the records it has stored when the registrar’s information changes; we will leave that synchronization problem for later.
While building it, the registrar’s office decides to make the API public, not private to CourseTracker. Other developers can build their own applications on the same course data, the way a public transit agency publishes its own schedule as an API for outside apps to use. CourseTracker becomes this API’s first consumer, not its only one.
The rest of this chapter designs that API: a public, read-only API for the course catalog. Keep in mind that the registrar’s system does a lot more than just maintain the catalog. Our goal is not to expose the registrar’s entire system, but only the catalog data that CourseTracker (or a similar system) needs.