Principles of API
The Application Programming Interface (API) based development plays a major role in modern architecture styles such as microservices or cloud native apps.
The Application Programming Interface (API) based development plays a major role in modern architecture styles such as microservices or cloud native apps. The API based development would offer better flexibility in release management, enterprise integrations, versioning and addressing heterogeneous client eco systems with uniform programming model.
API Design Principles
Following are few key principles put into practice while designing new API.
Care for Maintainability
Structure APIs that contains – Controller, Request/Response DTOs, Service, Dao and Domain object that mimics underlying business entity model
API will follow SOLID design principle – if applicable. Service and Dao layers programmed towards interfaces. Most modern frameworks like .NET Core / or Spring would offer this model implicitly
Do not clutter API with multiple responsibilities to reduce cost of deployment – one can easily slip into this trap while working under cost intensive environments (read as PaaS!)
Follow the consistent HTTP end-point semantics. For example: //products/get{Id}, //products/all, //products/create, //products/edit etc.
Consumer Focus
Uniform interface for external clients on various APIs offerings (Docs, Tests, Payloads etc.…)
Format JSON output to represent better entity naming (representing business domain)
Aggregate multiple service responses at controller level to reduce noise of API calls.
Consider using API Gateway while working on scale (Zuul, Ocelot, Azure API Gateways etc.)
Tailor the responses at gateway level – In order to cater multiple clients - Web, Mobile etc. and URI based caching
Leverage ASYNC capabilities offered by underlying REST api programming platforms while developing long processing APIs
Use Swagger for API documentation and testing
Include Azure AD/Other equivalents based authentication under PROD environment while accessing Swagger API docs
Third party integration should be event driven (Apache Kafka for example) / or web hooks
Version your APIs
Versioning is a crucial part of API design. It gives developers the ability to improve their API without breaking the client’s applications when new updates released. One of the major challenges surrounding exposing services is handling updates to the API contract. Clients may not want to update their applications when the API changes, so a versioning strategy becomes crucial. One can adopt many approaches while working on versioning. Following section briefly describes each of the approach(s).
o Versioning through URI Path
Example: http://www.example.com/api/1/products
Easy to understand, version specific responses can be cached as it has unique URI paths and most popular. This requires managing larger code base. Used in Twitter, FB, Airbnb etc.
o Versioning through query parameters
Example: http://www.example.com/api/products?version=1
Easy to understand, also it is easy to default the latest version
o Versioning through custom headers
Curl -H “Accepts-version: 1.0”
http://www.example.com/api/products
It does not clutter the URI with versioning information. But requires custom headers
o Easy Backward compatibility options
Not every change in API is breaking change that would require major revisions. Any changes to existing schema with additional attributes change in return messages etc. shall be easily accommodated with simple backward compatibility. In real life scenario, breaking changes are not very common. In addition, another approach would be spending lot of time during API design and having additional placeholder attributes to business model recommended. For example – the frequently used APIs can adopt this kind of approach; may not be elegant but it certainly come handy in quick change/rollout scenarios. One should always give more importance to accommodate changes via backward-compatible ways:
Additional attribute / entity inclusions
OR include Random / meaningless additional attributes to entity
Usage of PATCH vs PUT for updates (for example: ignore new changes, make a call PATCH with existing schema)
Practice API-first approach
Encourages the team collaboration while designing APIs
Usages of API description standards – RAML or Open API Specifications
APIs treated as first-class-citizens in entire eco system of application landscape
Ability to cater multiple clients (Mobile, Web etc.) with uniform / consistent data model (JSON for example)
Advocates development best practices – Mock APIs during integrations, teams can work in parallel, good developer experiences with auto-generated docs/test mocks (developers are primary consumers!)
Replay unit tests with good code coverage on important application functional scenarios
Choice of Standards and Tooling
Design APIs using standards –RESTful API Modeling Language (RAML) or Open API Specification (OAS)
Swagger for Open API and many RMAL compliant tools from Mulesoft. Swagger offers many automation benefits – Tests and Docs for example.
SwggerHub is commercial offering and very popular collaboration tool for among developers/architects
Restful Browser Plugins / Postman also widely used in API tests
Swagger vs. RAML: Both support popular languages - .NET, Go, Haskell, Java, JavaScript, Node.js, PHP, Python, Ruby, Scala
Monitor APIs
Log request and response payloads – preferably at Rest controller level
Use standard expression languages (e.g. Spring EL, Annotations etc…) to search responses for quicker diagnostic / root cause analysis
Use Correlation ID based / similar techniques to identify transaction based flow between multiple API calls
Tailor the error responses to have minimalistic yet effective logs – in order avoid heavy JSON persistence
Plan for Protection
Treat your APIs as your interface and make sure that the APIs do not disclose more information than the users are supposed to get.
Define, review, and enforce your API outputs. Chances are that many of the data that you store actually need not be available through your apps and APIs.
Reduce the risk of data exposure by collecting and storing only as little personal data as you really need.
Define design standards for on-premises, cloud and consumer facing APIs
Leverage API gateways / similar tools for general protection
Adhere to the zero-trust approach. Every API must assume that other application components have been compromised instead of blindly trusting them.
Following diagram briefly explains the principles shall be considered while designing APIs.
References
· https://swagger.io/specification/
· https://raml.org/
· https://github.com/microsoft/api-guidelines/blob/vNext/Guidelines.md
· https://swagger.io/resources/articles/adopting-an-api-first-approach/
· https://nordicapis.com/oas-vs-raml-whats-the-difference/
· https://blog.vsoftconsulting.com/blog/is-raml-or-swagger-better-for-building-apis
· https://www.baeldung.com/http-put-patch-difference-spring
· https://www.xmatters.com/blog/blog-four-rest-api-versioning-strategies/
· https://dzone.com/articles/api-security-weekly-issue-139