Skip to content

Notes on V3 Architecture

Greg Cobb edited this page Feb 2, 2017 · 8 revisions

This article is about code design/ architecture for the v3 API. For API design, see the API styleguide.

Preamble

The v2 API was architected to allow rapid generation of API endpoints by a small, dedicated team of developers. Now that Cloud Controller is a mature, open-source project with hundreds of contributors throughout the world, these architectural decisions have resulted in a few issues:

  • The framework that v2 is build on is powerful and semi-flexible, but is not maintained as a stand-alone tool so it is not used by any other projects or documented for common use. This makes it difficult for new developers and open-source contributors to learn its numerous eccentricities.
  • V2 endpoints are largely auto-generated, so it can be difficult to keep track of what endpoints exist. It can also be difficult to build endpoints that have custom behavior, not supported by the framework.
  • V2's reliance on model hooks results in a distribution of business logic across multiple units. This has a number of implications. First, it can be difficult for developers to follow and modify user workflows through the various hooks. Second, the hooks can result in unexpected, emergent behaviors for seemingly unrelated changes. Third, testing user workflows is difficult outside of top-level API tests.

The code design of the v3 api is a direct response to these issues. For example, the v3 API:

  • Uses several Rails libraries instead of a custom framework
  • Favors explicit vs generalized or meta-programmed code
  • Organizes business logic around user workflows (actions) instead of domain objects

Code Organization

Message Object

Message objects are have two responsibilities:

  1. Run superficial validations of user input. For example, validate JSON structure, check for unexpected keys, and verify types of parameters/ data.
  2. Serve as a value object to be used by subsequent objects in the request cycle.

Fetcher Object

The fetcher object’s responsibility is to get record(s) from the database. It also handles filtering based on user input.

Action Object

Action objects contain most of the business logic and typically implement user-facing workflows. Common examples include creation, deletion, or updating of a resource. Action objects make it easier to understand, test, and modify the v3 API's behavior.

Presenter Object

The presenter object handle rendering the response for the user’s request. It implements a to_hash method that when supplied to the render method in ActionController, results in rendering JSON.

Models

Models that are only exposed on the v3 api have very few responsibilities. They model associations between resources, provide convenience methods for accessing their data, and have basic validation to detect invalid states.

TBD

  • Code examples
  • Compositions (& Diagrams) of Objects
Clone this wiki locally