
Templar: A proxy to improve HTTP API interactions - evanphx
https://github.com/vektra/templar
======
akerl_
Based on the first sentence of the description, I was expecting a proxy that
added callback support to arbitrary APIs. I hit "[https://my-templar-
proxy/?real_url=$x&real_param_a=10&callba...](https://my-templar-
proxy/?real_url=$x&real_param_a=10&callback_url=$foo"), it hits the real API
and waits for the response, then hits my callback with it.

I feel like that might be more useful than what appears to be just a special-
purpose varnish/squid

~~~
evanphx
Author here! That's certainly an interesting feature that could be added. I
have on the future list to support sending responses back via AMQP. Your
callback scheme isn't much different than that.

~~~
jkarneges
Congrats on the announcement. Templar looks like a great project.

Re AMQP, I want to mention that our Zurl project does something similar, but
with ZeroMQ. It leads to some interesting possibilities:
[http://blog.fanout.io/2014/02/18/fun-with-zurl-the-http-
webs...](http://blog.fanout.io/2014/02/18/fun-with-zurl-the-http-websocket-
client-daemon/)

Zurl is not an HTTP proxy though, but a ZeroMQ gateway. Templar with async
responses would be much more generally useful to HTTP developers.

~~~
evanphx
I agree, async responses are a great tool. It's a question of figuring out a
good way of delivering them back to the client. Another option is a long poll
endpoint within Templar that it can deliver a stream of responses on. AMQP is
an easy option because it keeps Templar simple.

------
simonw
This could be really useful for sending outbound webhooks, if it grew a couple
of extra features:

1\. "Fire and forget" ability. It would be great if I could send a request
through Templar with an X-Templar-Fire-And-Forget: 1 HTTP header which means
"deliver the request in your own time, but return a 200 OK to my client
straight away so I don't have to wait for it.

2\. It would be great if it could "validate" the URLs going through it
somehow. When sending webhooks, it's important to be sure that they are going
to the rest of the internet and not being used to probe internal IPs/hostnames
of your own infrastructure. This is a bit of a fiddly problem, which is why it
would be nice to have a proxy like Templar take it on. Take a look at the
blocked_hosts section in [http://search.cpan.org/~bradfitz/LWPx-
ParanoidAgent-1.02/lib...](http://search.cpan.org/~bradfitz/LWPx-
ParanoidAgent-1.02/lib/LWPx/ParanoidAgent.pm) for an example. I'm not sure how
this would translate into X-Templar HTTP headers though.

~~~
evanphx
Fire-and-Forget is on the todo list. Since you're asking about it I'll bump it
up. The later, Templar could have an option that tell it to only connect to
public ips. Would that do it for ya?

~~~
simonw
Yes, that would be excellent - do you mean just public IP ranges?

One possible snag: I heard from a co-worker that if you are running on EC2 and
you make an HTTP request to another site that coincidentally is also hosted on
EC2 that traffic can sometimes be routed over a private IP range.

~~~
evanphx
That's good point actually, I could see that happening.

What is your concern about the url used? That they point at something a user
is trying to coerce you to hit? If so, that could be a public IP too..

~~~
jkarneges
It's more about hitting internal services, where there may not be adequate
protections in place. There's some earlier discussion here:
[https://news.ycombinator.com/item?id=7139176](https://news.ycombinator.com/item?id=7139176)

~~~
evanphx
Ah! Ok, I got it. Feels like the right way to handle this is the allow a
blacklist to be defined via config file, then applied as request, something
like "X-Templar-Blacklist: internal". The list would be a set of ip ranges and
thus you'd have to construct the list so that the EC2 => EC2 problem doesn't
crop up, but it's doable!

------
jfindley
The HTTPS implementation looks dangerous at first sight - it looks like an
attacker could very easily just strip the X-Templar-Upgrade out from the
request, and then end up with everything being un-encrypted - without the
client throwing any warnings.

Could you possibly provide more details of how you avoid this?

~~~
evanphx
Templar is designed to be used within your own infrastructure on a trusted
network, where you talk to it and it talks to the outside world.

An attacker would have to be already within your private network, and if they
were, they could observe the traffic in plain text already.

I think the confusion is around where Templar sits in relation to your app
making HTTP API calls and the services you want to talk to. I'm going to draw
up a diagram to help explain this better.

------
VeejayRampay
Note that this is by the excellent Evan Phoenix, creator of Rubinius, the Puma
concurrent web server for Ruby and tons of other awesome projects.

~~~
evanphx
Thanks Veejay!

------
aaronem
Maybe I'm missing the point here, but I'm not entirely sure I see the point
here.

What can Templar do for me that, say, nginx can't? All else equal, if nginx is
already in my stack and Templar is not, why do I want to adopt Templar, or
indeed even look twice at it?

~~~
evanphx
A great question. Nginx is not typically configured as a normal proxy but it
can certainly do it. A difference is that Templar gives you control of options
applied to each request differently rather than the same the same to all.

From timeouts to caching, one Templar can be used for all different kinds of
upstream APIs.

~~~
aaronem
Well, if it's worth adding a whole new layer to my stack to deal with this
kind of stuff, surely it's even more worth extending an existing layer to deal
with it; as a corollary, if I know enough about the problems I'm having to
know what I need Templar to do for me, then I know enough about them to know
what I need nginx to do for me, too.

Again, though, maybe I'm just missing the point here. Perhaps it would help to
know what use case prompted Templar's development.

~~~
falcolas
In my opinion, the draw is the ability to use it when connecting to third
party endpoints (so you can't control how they cache or how they respond) with
third party libraries (which means you lack fine grained control over timeouts
and caching on your end).

Personally, I'd rather gain the necessary control through the request
mechanisms, but for a quick-and-dirty solution, this would probably work
pretty well.

~~~
evanphx
It's very true that things like timeouts are done better within the client
library. But Templar can combine timeouts with caching, allowing an API to
appear to still be active and returning something even when it's just very
slow.

Because a cache is best when it's populated often, it make sense to put that
into a service that many different processes on different machines can use.

Everything within templar can be done by adding capabilities to client
libraries, no argument. But most client libraries don't provide these
capabilities in one programming language, let alone many of them. By having
the functional available as a service, Templar provides these capabilities
fairly transparently (and even more transparently in the future when there is
per/host and per/url configuration).

------
ing33k
Request collapsing looks like a nice feature . Regarding HTTPS support, I am
not really sure if I understood the details mentioned in the Docs properly .

Does Templar implement SSL Termination ?

~~~
evanphx
Templar does not do SSL termination because it does not terminate requests for
your api. It's designed to mediate connections between you and any APIs that
you use, protecting you against those APIs being unreliable.

------
paulspringett
The caching part looks really interesting -- have you considered adding
support for more fine-grained caching control, such as respecting etags and
last-modified times?

Thanks for sharing this!

~~~
evanphx
Yup! That's on the todo list. Auto-caching, as I'm calling it, would figure
out a how long to cache something for and then be able to later on use HEAD to
check if the url in question has changed.

That cache time could be as long as 5 seconds, so that Templar is checking
pretty often if the upstream has changed.

