Firstly, what a fantastic book, huge thanks to Paul Dix, it's been an
invaluable resource to me and a big influence on the architecture for
a platform we have built.
Our platform (http://hydra.io/) supports e-commerce of digital images
& artwork and its very first consuming app (http://artistic.ly) is now
in production. We will be opening the platform to the public, as well
as building our own apps on top of it. Apps might range from simple to
extensive web or mobile apps.
Our current 'inventory' consists of 4 REST JSON services and a client
gem with async HTTP for joins. The gem does a great job, and it's how
we currently use the platform in Artistic.ly. However, we want to open
the platform up with a public API, with the following goals:
* easy to consume with any language including client-side JavaScript
* probably a single URL endpoint which abstracts the fact that there
are multiple services
* common joins performed by the API to maximise the ease-of-use for
consuming apps (in other words: fetching a resource will automatically
include attributes it has joined from other services, where
appropriate)
* we will use the same public API access for our internal apps, to
maximise 'dogfooding'
I am currently considering achieving this by building a new REST JSON
public API (maybe a Sinatra app). This will use the existing gem to
provide a single, public API to the platform. From this point onwards,
we will always use this in our consuming apps, rather than the
existing gem. I envisage us creating an open-source gem and/or JS
library to provide easy access to this API.
I would love to hear anyone's thoughts on this problem, or my
described approach, including potential flaws, or alternative
suggestions.
Best regards
Joe
For the single URL endpoint concealing multiple services, the easiest
way to do it is just to stick a high speed proxy (like HA) in front of
everything. Just make sure each service has a top level part of the
path to make the proxy rules easy. Like:
/api/v1/service1/...
/api/v1/service2/...
As for creating an API that does the common joins, I'd say you have a
few options. You could create a new service that does it, or you could
just put it into one of the existing ones. Have another endpoint be
one that includes the join then have that service call out to the
other one.
Or, for the joining service you could just have one that fronts the
others like you said. Just make sure it's evented since you'll
probably spend most time waiting for IO. Good use case for node or
eventmachine.
I think the cleanest way to go is to avoid doing the joins for the
service clients. Let them do it. For things where the join almost
always happens, it should be part of the API to begin with. In that
case it might not make sense to split that data across services.
+1 on using the public API for your own app. I find that being a
consumer of your own API leads to cleaner, more elegant, and sensible
design.
Best,
Paul
> --
> You received this message because you are subscribed to the Google Groups "Service Oriented Design With Ruby" group.
> To post to this group, send email to service-oriented...@googlegroups.com.
> To unsubscribe from this group, send email to service-oriented-desig...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/service-oriented-design-with-ruby?hl=en.
>
This is really useful, I feel like the plan is coming together!
There is a point where there almost always is a join between two of
our services, I'm now quite sure that these need to be merged into a
single service. If we combine this with something like HAProxy, then
we have a solution that I'm a lot more comfortable with than my
original suggestion of a 'public API' service. An additional advantage
to this approach is that we can continue to use our existing client
gem, and release it for public access.
Huge thanks Paul, your response is very helpful.
All the best
Joe