There are two common ways to hook a service user to a service provider:
An API provides a library that you must link with to use the services. This tightly binds the client and server together. The API tends invade all code layers and creates massive dependencies between layers. It also tends to be simple to use.
A protocol defines a standard request response layer and a common transport. Nothing other than the standard binds the client and server together. Protocols are more complex to use as they are less direct and take a lot of serializing/deserializing/dispatching type logic.
I strongly argue for protocols because they provide the most flexibility. Program layers can evolve independently of each other. APIs, like CORBA, usually infect the top most layer down to the bottom most layer which create serious dependencies between layers. A change in one will require a change in the other layers.
For example, take the integration of a back tracking system with a source code control system. One package provided a CeePlusPlus
API to access their source code control system. They only provided the C++ code for a very limited set of platforms and compilers which made it very difficult to use across a broad array of clients. Plus most developers on the tool integration side don't use C++.
If they used a message protocol over HTTP as their interface then we could have used virtually any language from virtually any client to access their system. It would have been so nice.
Personally, I feel this is a FalseDichotomy
. You can (and often should) have both
an API and a Protocol. Basically, any Protocol can be wrapped with proxies to form an API. For a good example, look at the Apache SOAP implementation - SOAP is a protocol that will work with anything. However, the Apache Java implementation allows an API to be layered on top of it. It doesn't matter that the server you have to contact is written in Visual Basic or Visual C++ - the Java API can still work as long as you can describe the interface. That's where the third part becomes useful - an InterfaceDefinitionLanguage
. For the SimpleObjectAccessProtocol
, the WebServicesDescriptionLanguage
serves as the IDL. In fact, that was one of the good things about CORBA - if you had the IDL you could generate a client for any language, regardless of what the server was written in. -- KyleBrown
You can wrap an API around a protocol but you can't wrap a protocol around an API because the API implementation becomes required which means the protocol doesn't exist on its own.
I would debate that assertion. I think you can
wrap a protocol around an API. I've done it many times. You simply have to write something that calls into the API and then make it accessible through a protocol.
You know we're basically violently agreeing that you often need both. That's the idea of HalfObjectPlusProtocol
. -- KyleBrown
In my mind there is a clear distinction between the way you implement (an API), and what you agree with a service provider (ideally a protocol). So you agree to talk SOAP or something simpler. Then you write or choose an API that implements the protocol. I strongly believe that standardizing on SOAP allows for more independent growth than mandating Apache AXIS. -- Brendan Johnston
Wrapping an API is indeed possible, and desirable. Where I work we're stuck with a poorly-designed proprietary user access control system. I first came up with an interface to represent a generic security service, then implemented it as a SOAP client and server side. FacadePattern
. Now when we are finally blessed with a better security system it will be possible to implement a layer to call into it that implements the same generic interface, saving the rest of the system from being tied to the junk we have now. -- StevenNewton
Another example of API wrapping: we took a C++ API and wrapped it in a dynamically typed interface (e.g. each parameter is like a VB Variant/Java Object/Python Object/dotNET Object/Excel XLOPER) and then provided simple language adaptors to translate back and forth. Then people could add a thin statically typed layer in the language they're working in if they wanted it.
The key advantage of this approach is availability and simplicity: it's far easier to get a single generic language translation layer going, than to entangle the problem of C++/language bindings with the problem of interfacing with various type systems.
We're currently working on automatic generation of the statically typed layer, since for instance Java projects in different areas of our organization typically have different type systems to interface with at quite a low level, since everyone seems to have their own replacement for the broken Date class, and it takes too long to write them by hand.
The layers look something like this:
[Type System-specific Statically Typed Wrappers] <- "API"
[Language-specific Dynamically-typed entry point] <- "protocol"
[C++ Dynamically-typed API] <- "protocol"
[C++ Statically-typed API] <- "API"
The bottom 2 layers are in common between all systems and languages. The next is written once for each language. The next is written once for each type system (we have families of applications that share type systems). And then you get the more specific stuff.
An API ... tightly binds the client and server together
A protocol defines a standard .... Nothing other than the standard binds the client and server together.
Most of the discussions I have seen would argue that the API provides less coupling between client and server, not more. With the protocol approach, the client and server must agree implicitly on how to encode and interpret the data being passed. This requires shared or retyped files to identify command and data. XML provides a slightly more organized way to handle it, though this quickly becomes a duplication of the API approach. To do remote operations, the client and server simply must agree on commands and data and there is no linker to help coordinate this agreement.
There's no tighter coupling than a language binding. APIs require language bindings. If I don't want to use their language, as has happened many times, then I am SOL. With a protocol all I need is the underlying communication library ported to a language library once, which is much more common. Sockets are everywhere. That makes it easy to write http/SOAP on top of that for any environment supporting sockets. Contrast that with porting an API to C++, Perl, Java, Python, Ruby, Lisp, Haskell, etc. And saying I am to use foreign function import feature to a binary is tight coupling as well.
Yes, the pattern we typically follow is client uses proxy (which implements api), proxy talks protocol to skel. skel makes function calls on the same exact api the proxy implemented. This allows 2 things:
1. Other languages can still talk the protocol.
2. If product mgmt decides we need to implement a new protocol, I just write a new skel without ever having to rewrite the business logic which I have seen done many times when there was no API.
Both API and protocol can specify a contract between client and server. However, API is always programming language dependent, protocol isn't. Although there are some tools for creating language bindings easily, extra efforts have to be made. A notable example is JMS and AMQP. JMS is a Java API for message queue. Client can talk to any JMS compliant message queues by the same JMS API, in case client uses java. There is no wire level interoperability guarantee. That's why AMQP is developed. Also we can think about Servlet API. If we only have Servlet API and don't have HTTP, what would happen? ASP and PHP will not have been existed! Protocol can provide platform independence and language independence. That's why protocol is more pervasive than API.
Essentially, "API vs Protocol" is equivalent to "LocalProcedureCall
Agreement on marshalling technique for a protocol is much alike argument ordering and registers utilization convention of an API.
You use an API, but you speak a protocol.
So, a protocol has - by definition - a wider applicability.
An API is just something that can or must be served.