REST API Design brought us to a point where we are capable of managing applications in our own way. Despite how the UI is implemented, we can automate and integrate to other apps easier than before. Even though we still see companies struggling to manage their app ecosystems and speed up the value stream, it's time to accept Management API limitation as an interface to our end-users and to understand that we shouldn't be managing applications, but resources. A Declarative API through a DRD (Declarative Resource Definition) has been largely used as a better approach.
Management APIs are a de facto standard; many applications from different areas provide it, i.e. Apigee, PingFederate, and ArcGIS Server. This approach promotes the ability to manage an application without relying on UI or app, and enables teams to automate the process, which saves time and is less error-prone — a significant improvement to our daily routine while wearing the developer or system administrator hats.
When we take a closer look at an automation script or tool developed using a Management API, it's clear that it becomes more complex than it was designed for. Let's check a real example. Apigee, Google's Application Gateway, provides a Management API to manage the App Resource (Client in OAuthV2). A data structure with app name, client id and secret, owner, and a list of API products (Resource Servers in OAuthV2) could be fair enough, but the API requires the following requests to create an App Resource:
- POST /developers to create the owner;
- POST /apps to create the app;
- POST /apps/keys to create a client id and secret;
- DELETE /apps/keys/<client_id> to delete the default key created during the /app creation;
- POST /apps/keys/<client_id> to add access to API products.
It's already big enough, but if we have to avoid some steps to get executed twice and add one JSON file for each request, it's clear how far we are from just managing a few JSON files through HTTP requests.
During the last decade, you were introduced to different mechanisms to manage configurations. Provision tools like Puppet, Chef, and Ansible introduced us to the Declarative API, which from the desired state, an engine sets up the entire operating system. Kubernetes took advantage of the Declarative API in such a way that you can write your resource file once and apply it among different cloud vendors. As stated by Kief Morris in his book Infrastructure as Code, “defining all your stuff ‘as code’ is a core practice for making changes rapidly and reliably.”
By relying on a DRD, REST API, Database Model and Protocol complexities are hidden from the end-users, and you are able to provide a concise and meaningful resource description. Your team can store the DRD in a repository that is available for quality checkers and tools that enforce security policies. The DRD can be defined by a specification, allowing applications to implement it and make the resource management portable across different vendors.
This indeed benefits Management APIs mostly, although apps that share the following characteristics can also benefit from a Declarative Management API:
- Low data change rate;
- Strong integration requirements;
- Resources owned by Teams;
- Resource security constraints;
- Versioned resource.
DRD applied on a real-world example
We took the real example provided before and described it as a Declarative Resource Definition in YAML syntax:
--- owner: "Order Team" client: name: "Order App" client-id: "AGAWG$#qh5erg%w65hrthdfsh^U%758-F4K3" secret: "SDW&s-f4k3#35&gad823" resource-servers: - shipment-app: id: 12523-512352-23523-1235235 - fulfillment-app: id: 32153-435S425-SE3324555-0013434F name: "Fulfillment Application"
It looks similar to an App Resource UI Page, and this is a good measure of how concise your DRD is. Once it's defined, the next step is designing an application that consumes the RESTful Management API and applies the desired state described as DRD.
The application can be a simple command-line interface that runs locally and applies the resource state against the server, or it can be a server application that is hooked to the version control system. Whenever the resource changes, the server application will be triggered and apply the desired state to the Management API.
While this improves resource management, it raises a few security concerns, so it's important to restrict access on who can edit the DRD, add a peer review process to approve merge requests to the DRD, and retrieve secrets from a vault solution.
There are more benefits to this design that can be helpful in migration projects or in business cases where a domain-specific language might be more appropriate than a DRD. However, the most important achievement is provisioning a meaningful resource interface that can leverage the Application Management to a Company Resource Management.
Disclaimer: The statements and opinions expressed in this article are those of the author(s) and do not necessarily reflect the positions of Thoughtworks.