Ian Bicking: the old part of his blog

Re: HTTP(ish) all the way down

Yeah, configuration/deployment and testing have been the hardest problems I've come up against with this architecture and ones that I don't feel like I have a good solution to yet.

The WSGI/Paste approach is interesting. Unfortunately, my apps still need to work in a very heterogeneous environment so if I put everything into just a WSGI stack, I lose the ability to reuse it across languages as easily. Unified configuration is tempting enough that I might go for it sometime though.

The idea of building your app as a bunch of WSGI components and later breaking them out into seperate REST apps as needed has crossed my mind as well. My thought on it was to go the other way though and have a library and registry that abstracts the difference away. So you would build all your components as WSGI components but call them through a fully HTTP looking API. Then, there would be a registry somewhere that knows which urls map to actual seperate applications and which can be silently converted to WSGI calls. So you do something like:

from magic_REST_WSGI_library import GET
tags = GET("http://tasty.example.com/item/foo/")

and a registry that magic_REST_WSGI_library reads knows that "tasty.example.com" can really be mapped to a WSGI component and called in process. That way, when that component does need to be moved out to its own machine or written in a different language or something, no code has to be changed; just an update to the registry telling it that requests to that service now have to be proper HTTP requests. It's sort of a "have your cake and eat it too" approach. You get the flexibility and loose coupling of REST components but, if you happen to write all your components in python and keep them WSGI compatible, you can keep the performance and centralized configuration of having them all in-process. Maybe this is something that Paste could help with.

The other observation I have on performance of applications built up out of small REST applications is that asynchronous requests are your friend. Latency does add up quickly and the way to avoid it is to avoid synchronous communication any time you can. Looking at how Erlang applications are structured is advisable.

Comment on HTTP(ish) all the way down
by anders

Comments:

The WSGI/Paste approach is interesting. Unfortunately, my apps still need to work in a very heterogeneous environment so if I put everything into just a WSGI stack, I lose the ability to reuse it across languages as easily. Unified configuration is tempting enough that I might go for it sometime though.

You'd still be making HTTPish calls between applications. WSGI (and even Paste) doesn't relate to that; it just makes it more manageable when you have a bunch of WSGI/Paste pieces. Well, WSGI does give you a backdoor to make requests on behalf of the original user, since it has a slightly larger concept of a request than what can be embedded in HTTP, including things like trusted attributes (keys that don't start with HTTP_).

Of course, you can opt not to use these things and stick to what can be represented in HTTP. But it can be very tempting.

And of course, middleware is breaking out of what HTTP can give you. Though it'd be neat if you could run PHP with FastCGI under a WSGI stack.

Anyway, there's nothing stopping you from sticking to language-neutral constructs when using WSGI, and when WSGI-specific constructs get used it's fairly explicit so you know what you are getting into.

The idea of building your app as a bunch of WSGI components and later breaking them out into seperate REST apps as needed has crossed my mind as well. My thought on it was to go the other way though and have a library and registry that abstracts the difference away. So you would build all your components as WSGI components but call them through a fully HTTP looking API. Then, there would be a registry somewhere that knows which urls map to actual seperate applications and which can be silently converted to WSGI calls.

Titus' WSGI intercept does just this transparently for anything using urllib/2.

For something that requires less configuration and is probably a bit faster of a path, paste.recursive offers a model where you phrase it as a WSGI request. By adding to that, you could translate the request into an actual HTTP request if it was outside of the WSGI stack. paste.recursive isn't exactly the right match (and paste.proxy isn't exactly right for making a WSGI request into an HTTP request), but it would be very close to that. You wouldn't need configuration, because by keeping note of the request on the way in you can automatically determine where the root of the WSGI server is. Though it could be tricky if you have fancy dispatching, like virtual host dispatching, which means that the server is capable of internally responding to more requests than you might think.

The other observation I have on performance of applications built up out of small REST applications is that asynchronous requests are your friend.

I like the idea of using callbacks more, though I haven't tried it in practice. Something like "do this, then when you are done POST to this URL with the results". Of course, many UIs need synchronous actions (people like to know that when they do something it is actually done), so you can't solve all latency problems this way.

# Ian Bicking