The API pattern bind IO functionality to business functionality by binding IO state either through annotation (ie JAX) or by extending a RestfulController. As a result, the data associated IO State cannot be shared with the architectural instances because it is bound to the controller. This creates architectural cross cutting concerns not only with the functionality but also with the data. By abstracting the functionality, we can create a versioned data object for IO state that can be shared,cached,synced,reloaded on the fly for all architectural instances without having to restart any instance. This greatly improve automation, performance and flow of api applications and architecture.
work on title
perhaps something less intimidating; more relatable to work they are doing without ‘fancy names’
What I am about to show you will:
amaze
anger
shock
annoy
astound
and confuse
can be controversial
May not get it immediately. Those that do will walk out of here looking at api development with new eyes… thats a promise. You will never see them the same way again.
I’m going to tell you right now that this is a rethinking of the api pattern and a lot of its premises in how it is implemented so if you are not ready for a bumpy ride or if you have a weak heart, I’ll give you a moment to step outside…
… ok and with that…
let me ask you this…
the reason I bring this up…
This number used to be around 50% in 2005. Now, it’s roughly 25-30% now… and going down.
the api pattern was originally designed for software applications (centralized architecture)
but what is an api?
In Short: An API is a separation of concern of I/O for functionality of resource management
- For example…
Now the most common way is…api as software pattern
This is ONE software application… or a piece of software contained within ONE software application (creating a centralized architecture).
Here concerns are separated
standardized input/output to a separation of concern within the application
the separation of concern binds communication logic to a service which does resource mngmt (ie the resource that is requested, manipulated and returned)
api as architectural pattern is api as service amongst multiple connected software services (creating a distributed architecture).
The api pattern for architecture is IDENTICAL except the separation of concern is a software component separated from other software components… not concerns separated from other concerns.
In a distributed architecture, we can see:
there is already I/O and resource management in the standard MVC application
with request/response coming/going to other architectural components
… everything is mapped.
This is STILL a centralized architecture at this point but has the POTENTIAL to be more easily become a DISTRIBUTED architecture
Unfortunately, we didn’t understand that api is architecture as well as software and so when applying it to the web, we applied the the software pattern rather than the architectural pattern
For as you see when we add other services, we can share the I/O flow.
But now we have a problem…
Current implementations in distributed architectures are not so NEAT.
This creates a mixed implementation.
creating massive redundancy and duplication with every method.
Software confusion: where do we handle batch jobs? Where do we do checking? how do we handle loopback and redirect?
Architectural confusion: how do we share with external services? What do we share? How do we keep things in sync across architectural components and api instance?
We literally have to duplicate this information with EVERY method
then , as you can see in the body, we have to do additional checks for multiple roles handling this.
This can’t be separated and moved to the PROXY without duplicating or entanglement making it impossible to synchronize this data.
Thus overtime this data changes, it requires ‘human intervention’ to make sure ever instance of it remains synchronized due to this ‘hard coding’.
having to manually code the flow creates massive code duplication
it also makes it so you have to shut down the server and bring it back up overtime you want to add something new to the flow
by using existing communication layer, this reduces duplication and allows you to merely uses properties as toggles
finally, flow cannot be easily isolated and moved to separate server without creating entirely separate project; as separate layer, can be detected at proxy and sent to separate server to have separate functionality handled so as to not affect unaffected processes.
example: api batching
having to manually code the flow creates massive code duplication
it also makes it so you have to shut down the server and bring it back up overtime you want to add something new to the flow
by using existing communication layer, this reduces duplication and allows you to merely uses properties as toggles
finally, flow cannot be easily isolated and moved to separate server without creating entirely separate project; as separate layer, can be detected at proxy and sent to separate server to have separate functionality handled so as to not affect unaffected processes.
example: api batching
When I showed this to Netflix and how their tools like Zuul were doing precisely this, this is how the api manager responded.
And that not all…
Data stored/used in annotations cannot be shared with architectural components without duplication.
Annotations cant be cached as they would exist in two places: the controllers and the cache; this data would be impossible to sychronize. This is what is known as an architectural cross cutting concern as it creates duplication and/or entanglement.
Thus at this point we can easily state…
These two concepts cannot be reconciled without created a cross cutting concern every time.
Mixing the two causes api as an architectural pattern to DEFAULT to being an api as a software pattern and thus a centralized architecture.
The modern web api is a mixture of these two and as such has issues in scaling in distributed architectures as a result of creating this architectural cross cutting concern.
The solution is to apply the api pattern as architecture and not as software. Only then can you resolve issue with architectural components as you scale your application.
we need to see api as separation of SERVICE rather than separation of concern
we don’t need to add anything here as all the necessary structure is already in place
we just need to code our logic in correct places (communication logic in handler interceptor and business logic in controllers)
By preloading the IO state at runtime, we can:
share with all subscribed services to the api through a pub/sub model via web hooks
all the data contained in annotations act as rules associated with the uri endpoint
by containing all those rules in one file and caching that data, we can share it with the other architectural components
then we can change and it on the fly and reload without having to restart any components and subscribed services will have changes published to them through web hooks
no its not a college in the midwest
There are two types of IO state…
What does it do?
It is a complete separation
well in Grails, without giving away too much of the secret sauce right now, I did it in the handler interceptor like this…
You’ll notice in this example the controller is doing ALOT of additional work:
role checking
request.method enforcement
uri mapping
input checking
A lot of I/O and security that has been tacked on; these are not part of its ‘separation of concern’ and need to be shared with the architectural components.
The controller is now a proper separation of concern and is STRICTLY focused on business logic
At runtime, we bootstrap the files so that are loaded and cached…
Then in urlmapping, we create a default mapping based on app version to handle all mappings…
The controller is now a proper separation of concern and is STRICTLY focused on business logic
The controller is now a proper separation of concern and is STRICTLY focused on business logic