subscribe via RSS
New to the subject of realtime APIs? This article is the place to start! We’ll discuss the most common design approaches and their pros/cons, as well as link to the documentation of 16 public realtime APIs that you can use for inspiration.
Zurl is an HTTP client daemon based on libcurl that makes outbound HTTP requests asynchronously. It’s super useful for invoking Webhooks. Zurl supports fire-and-forget invocation, error monitoring, and protection from evil callback URLs. Sounds pretty great, right? Let’s see how it’s done.
Zurl is a gateway that converts between ZeroMQ messages and outbound HTTP requests or WebSocket connections. It gives you powerful access to these protocols from within a message-oriented architecture. The following diagram shows how Zurl may fit in among the entities involved:
Any number of workers can contact any number of HTTP or WebSocket servers, and Zurl will perform conversions to/from ZeroMQ messages as necessary. It uses libcurl under the hood.
The format of the messages exchanged between workers and Zurl is described by the ZHTTP protocol. ZHTTP is an abstraction of HTTP using JSON-formatted or TNetString-formatted messages. The protocol makes it easy to work with HTTP at a high level, without needing to worry about details such as persistent connections or chunking. Zurl takes care of those things for you when gatewaying to the servers.
HTTP callbacks (aka Webhooks) are great for sending notifications to remote servers in realtime. In most setups, the URLs to contact are provided by foreign entities. All your application needs to do is allow such URLs to be registered, and then hit them whenever interesting things happen. Easy enough, right?
Not so fast. What if someone provides a URL such as
http://localhost:10000/destructive-command/and you’ve got an internal web service running on that port? Under normal circumstances, you might not expect this service to be accessible from the outside. Perhaps you have a firewall, or perhaps the internal service binds explicitly to the localhost interface. Either way, the HTTP callback pattern provides attackers an avenue to access this service from within your internal network, bypassing these kinds of expected security measures.
I’m a big fan of ZeroMQ, the peer-to-peer message queuing system. If you’ve never heard of it before, go check out the project’s website. You may need to read the guide and then wait a day or two before it hits you, but it’s the kind of simple, brilliant technology that will eventually make you wonder, “golly, why isn’t everything built this way?” What really sold me on the concept is the Mongrel2 web server. Real-time HTTP becomes a lot easier when you can exchange requests and responses asynchronously over a message queue, and the fact that it’s peer to peer makes the approach practical and easy to scale. Fanout Cloud uses ZeroMQ for the majority of communication between server nodes and components. While Fanout Cloud does support XMPP features, it notably does not use XMPP for internal communication. More on that decision in a future article.
As Fanout needs to handle both inbound HTTP and outbound HTTP, I thought it would be neat to try and write essentially the inverse of Mongrel2. The result is Zurl, an event-driven server that makes HTTP requests. The software has been released as open source, so it is free to download and use on your own machines.