This is part of a series on Web API design. The intro post is here.
When some developers think about the Google Maps API, they may envision a sea of
GOverviewMapControls, and the like. But really, it boils down to 2 things:
These two classes are interfaces in the API, and every class that is a visual item on the map extends from one of those two. Conceptually, a
GOverlay is something that moves when the map moves and is somehow related to latitude/longitude coordinates, and a
GControl is something that always stays in the same place, regardless of map movement. The screenshot below points to various examples in a standard maps mashup:
To add one of these to the map, a developer just calls addOverlay or addControl:
map.addControl(new GScaleControl()); map.addOverlay(new GMarker(new LatLng(37, -122));
To remove them, they call
There are some mapping APIs out there with calls like
addPolyline. This is is a bad idea for several reasons. It means you need an additional method each time you add a new visual class (bloating your API), and it likely also makes it hard for developers to extend the API. With generic methods like
addControl, you can add a custom extension the *same way* you add a native class - so newbie developers don't have to learn a new syntax to add one to their map.
Along with using generic methods for adding stuff to the map, we can also take advantage of the interface to make our events more generic. A developer can listen to
"removeoverlay" to find out when any overlay has been added to the map, and when they listen to a
"click" event on the map, their callback gets passed in whatever
GOverlay was clicked on. This means that whenever we add a new type of overlay to our API, the developer can continue using the same events they were before. We do often add specific events for each overlay later, but it's nice that the generic ones come for free.
And something for the advanced developers...
These interfaces make our API infinitely extensible in a standard way, and they're the reason I used the API for my personal and research projects even before working for Google. If I have a fundamental aesthetic issue with our
GLargeMapControl3D, then I can simply create my own control (ExtLargeMapControl). If I want to visualize 5,000 markers, and
GMarker is simply too full-featured and heavyweight for the job, then I can create my own lightweight marker (MarkerLight). If I want to visualize my points as <div>-based bar graphs instead of <img>-based markers, then I can create my own overlay (Bar).
To extend the interfaces requires defining only a few minimal methods:
GOverlay: initialize, redraw, remove
initialize method, called when
addOverlay is invoked, should create DOM objects for the overlay and append them to the desired map pane (there are several). The
redraw method is called whenever the map moves, and it should re-position the overlay depending on the new latitude/longitude -> pixel mapping. The
remove method, called when
removeOverlay is invoked, should clean up any DOM objects created by the overlay. More info and an example is in the docs.
GControl: initialize, getDefaultPosition
The initialize method, called when addControl is invoked, should create and return the div for the control. The getDefaultPosition method should returns the recommended position for the control. There is no remove method, since the
initialize method returned a <div> that the map can remove whenever
removeControl is invoked. More info and an example is in the docs.
Don't forget the actual API engineers...
Along the same lines, these interfaces also make API development easier for internal developers. If they want to add a visual class to the API, they just need to figure out whether it's a control or an overlay, define the methods, document that the new class exists, and external developers will use their existing familiarity with
addOverlay to add it to their map.
It can't all be fluffy rainbows and unicorns...
We've certainly made a few mistakes along the way with the interfaces - but this post is getting long, so I'll save those for later.
To sum it all up...
The interfaces are easy for newbie developers to understand, easy for advanced developers to extend, and easy for internal engineers to implement. Beautiful.