I just pushed a new topic branch, x-new-api, which contains, well, a
new API for gophercloud. The 'x' means it's experimental. Or
EXTREME!! Or maybe both.
Lately, a number of people have been contributing support for
extensions, and requesting new APIs, and other such things which,
honestly, if left unchecked, will pollute the software's namespace in
several different ways.
First, everything sits in a single directory with the current API.
This will inevitably break after some amount of time, especially as
support for multiple kinds of providers (e.g., AWS) comes in the
future. But, perhaps more importantly, the interfaces.go file just
keeps getting bigger, and there's no indication from the source code
of which method corresponds to which extension, if it's an extension
at all. There's an over-abundance of data structures which pollutes
the
godoc.org representation of the interface, but which serve no
user-callable purpose.
In short, it's like WIndows 3.1 DLL Hell all over again, but with Go.
So, I created x-new-api as an attempt at refactoring the design a bit.
I claim it's a better design on the following basis:
1) Finer grained directory hierarchy allows for reduced concerns over
name collisions. Consider that both networking AND compute services
have extensions for "security groups."
2) Support for company-specific products. In the x-new-api branch,
you'll see an (very incomplete) implementation of Rackspace's Cloud
Monitoring API implementation. Note that it follows the same overall
directory structure as company agnostic offerings, e.g., OpenStack.
Note also that most if not all things related to Rackspace's
monitoring API remains confined to its own namespace. No more
irrelevant tweaks to other Gophercloud resources.
3) A clean separation of request and response processing. Presently,
the API philosophy is to make each request/response cycle look
indistinguishable from a normal subroutine call. This works great for
the simpler API calls, but starts to break down as soon as customized
processing becomes necessary. For example, authentication and the
need for raw access to the service catalog. To remedy this, I employ
a lot of design inspired by the carrier-rider pattern (or related
constructs). As with a database, the result of a request is just a
blob of data (the "carrier"). You now need to create data accessors
("riders") which interprets the data. It takes, maybe, one or two
extra steps, but the results seem much cleaner to me.
4) Better support for concurrency in the future -- I've not
implemented anything to support this yet (I only had six hours to
write this!), but the infrastructure is there. If concurrency issues
become an issue, it's much easier to add relevant locking to the
carrier than it is to every call-site of a rider. Since riders
usually hold a reference to their associated carrier, this is easy to
accomplish.
5) It feels significantly more like idiomatic Go to me than the
current interface.
6) No built-in means to locate a service -- it's all up to you now
(and it's not that hard). This is an important change; it turns out
automating this potentially opens our users up to legal liabilities
because of its potential to inadvertently select a service in an
unintended region. If the old way is still desirable, I can move it
into a utils package for easy, but deliberate, reference.
7) As currently implemented, x-new-api does not break the existing
API; it's completely separate. Thus, legacy software would continue
to compile with the newer implementation. However, legacy software
would NOT be able to use new API features. Thus, it's compatible with
the idea of a "deprecation period," where we remove the legacy API
after, say, three to six months, allowing for users to upgrade their
software accordingly.
Since we've been discussing the possibility of making breaking changes
recently, I decided to throw this together and see what people think.
What do you like about it? What do you not like? How would you
change things? I'd love to hear from you.
NOTE: I know that TravisCI did not pass the build in the x-new-api
branch. Not sure why, but I can definitely stand behind the claim
that it "works for me". If folks like the new API, I can spend the
time to debug TravisCI issues.
--
Samuel A. Falvo II