TLDR; If you are putting business logic of your domain in your API Layer (which is the presentation layer of your service), you are doing it wrong.
Layered (Tiered or N-Tiered) Architecture is a software design pattern that implements a software system in a stack of layers. Each layer has a distinct responsibility and has a dependency upon the deeper layer - with the deepest layer normally accessing a relational database.
This pattern, also known as the Layers pattern, was formalised in the book Pattern-Oriented Software Architecture: Layers pattern "helps to structure applications that can be
decomposed into groups of subtasks in which each group of subtasks is at a particular level of abstraction." This pattern emerged as a replacement to the Client-Server architecture and became very popular in late 90s and early 2000s.
Service Oriented Architecture (SOA) did not change the popularity and importance of tiered architecture since each service contains the tiers inside it (Figure 1)
|Figure 1 - Layered Architecture in SOA|
There are different approaches in identifying and naming layers across a system stack. Historically, three tiers have been identified: Presentation Layer, Business Layer and Data Access Layer (Figure 2).
|Figure 2 - Traditional Layers|
- Presentation Layer deals with user interactions
- Business Layer contains the business logic of the domain
- Data Access Layer is concerned with the persistence of the domain objects
However, Eric Evans in his Domain Driven Design book introduced an alternative layering which was a better fit for DDD: Presentation Layer, Application Layer, Domain Layer and Infrastructure Layer. (Figure 3)
|Figure 3 - Layers according to DDD (two alternative interpretations)|
In this model, responsibilities of each layer is defined as below:
- Presentation Layer has the same responsibility as the traditional model: user interaction (user could equally be a machine or human)
- Application Layer which I prefer to call Workflow Layer is the thin layer that connects and coordinates coarse granular business tasks. This layer can have state regarding the state of a business activity.
- Domain Layer is the heart of the system which contains all the business logic
- Infrastructure Layer is responsible for persistence, passing messages to buses and providing a framework and utility across other layers. As such, all layers could have access to this layer.
API LayerIn none of the above we saw any mention of an API Layer, so what is an API Layer? API Layer is the outermost layer of a service and is concerned with presentation of a bounded context services through the API. In other words, in an SOA, we can call the Presentation Layer of an SOA Services its API Layer.
This layer was very thin or non-existent in services exposed through SOAP but it is an important layer when it comes to REST. The reason for its lack of importance in SOAP services is the fact that an RPC service can be easily exposed through SOAP with some configuration and little or no coding - using various tools and frameworks that make this possible with a click of a button. WCF is an example of this in the Microsoft stack while IBM Websphere is a popular tool in the Java world capable of achieving this.
API Layer ResponsibilitiesWith REST, however, API requires a distinct layer that is responsible for translating the HTTP semantics to and from the code world. It also responsible for cross-cutting concerns such as monitoring, logging, identity, etc. We will be looking into each and expanding the meaning and examples.
|Table 1 - API Layer responsibilities (in REST)|
|Figure 4 - This is IBM's view of an API Layer according to this article. |
However, I will call it How Not To Design An API LAYER.
HTTP SemanticsTalking HTTP is the most important responsibility of a REST API. HTTP provides different axis of sending intent or data which cannot be easily mapped to an RPC method's parameters. This problem is known as the impedance mismatch between RPC and HTTP.
|Figure 5 - Impedance mismatch between HTTP/REST and RPC. |
Challenge of shaping HTTP requests and responses from RPC methods
is the most important responsibility of the API Layer. (From the book Pro ASP.NET Web API)
Table 2 lists important HTTP semantics that are responsibility of a REST API Layer.
|Table 2 - HTTP Semantics that are responsibility of a REST API Layer|
MonitoringIf you have an API that you do not monitor its health, performance and usage, then this is not a serious API. Bear in mind that Quality of Service (QoS) is one of the mainstays of an API which can be translated into SLA. Regardless of whether your API is public or private, you have to monitor your API against its baseline.
Identity and AuthenticationVery rarely, if ever, an API allows anonymous clients. Even if your API is free, you should build an identity mechanism such as an API Key. API Layer is responsible for turning identity/authentication mechanisms (Basic Authentication, OAuth, OAuth 2.0, Windows Authentication) into rich claim-based identity.
Please note that we did not mention Authorization. Authorization is a concern of deeper layers of the system and fully ingrained with Business Logic - as such is not suited for implementation in the API Layer.
Logging, tracing and documentationDeveloping against an API is not an easy task and you should make it very easy for the clients of your API to be able to build, debug and deploy. This is most neglected feature of an API that can endanger success of your public API or private API within a big enterprise.
Monetisation and Capping?Similar to Authorization, I am on the belief that monetisation and usage capping of an API is heavily dependent on business logic and information that are available in deeper layers. As such, I believe that monetisation and usage capping of an API must be implemented in deeper layers and not in the API Layer.
What about the relationship of the API with Server-side generated views?A common question that crops up in the stackoverflow is how to lay out the architecture of web applications that historically were based around Server-side MVC Frameworks. For example, should a RoR web application use a Ruby-based API layer? Or if you are in the Microsoft world, should an ASP.NET MVC application use ASP.NET Web API services?
Well it depends. API Layer and Server-side MVC Frameworks both sit at the Presentation Layer. So you should not really add the networking and serialisation overhead of accessing an API Layer from Server-side MVC Frameworks if they are part of the same application. As we said, API Layer is a thin layer that is only responsible with the API centric responsibilities. In most cases, MVC Frameworks should directly use deeper layers of the system and sit side-by-side with the API Layer. However, if API Layer is the presentation layer of an SOA service and the MVC Framework uses multiple APIs to build the views, then it is OK to separate it from the API Layer.