• No results found

No Hierarchy? Use Commas or Semicolons

In document RESTful Web Services (Page 144-147)

The next resources I need to name are geographic points on the globe, represented by latitude and longitude. Latitude and longitude are tied together, so a hierarchy isn’t appropriate. A URI like /Earth/24.9195/17.821 doesn’t make sense. The slash makes it look like longitude is a subordinate concept to latitude, the way /Earth/Chicago sig- nals that Chicago is part of Earth.

Instead of using the slash to put two pieces of scoping information into a hierarchy, I recommend combining them on the same level of a hierarchy with a punctuation char- acter: usually the semicolon or the comma. I’m going to use a comma to separate lat- itude and longitude. This yields URIs like the following:

• http://maps.example.com/Earth/24.9195,17.821 • http://maps.example.com/Venus/3,-80

Latitude and longitude can also be used as scoping information to uniquely identify a named place. A human would probably identify Mount Rushmore as /Earth/USA/Mount %20Rushmore or as /v1/Earth/USA/SD/Mount%20Rushmore, but /v1/Earth/43.9;-103.46/ Mount%20Rushmore would be more precise.

From a URI design perspective, the interesting thing here is that I’m stuffing two pieces of scoping information into one path variable. The first path variable denotes a planet, and the second one denotes both latitude and longitude. This kind of URI may look a little strange, because not many web sites or services use them right now, but they’re catching on.

I recommend using commas when the order of the scoping information is important, and semicolons when the order doesn’t matter. In this case the order matters: if you switch latitude and longitude, you get a different point on the planet. So I used commas to separate the two numbers. It doesn’t hurt that people already use commas in written language to separate latitude and longitude: URIs should use our existing conventions when possible.

In another case the order might not matter. Consider a web service that lets you mix colors of paint to get the shade you want. If you’re mixing red and blue paint, it doesn’t matter whether you pour the red into the blue or the blue into the red: you get purple either way. So the URI /color-blends/red;blue identifies the same resource as /color- blends/blue;red. I think the semicolon is better than the comma here, because the order doesn’t matter. This is just a typographical convention, but it helps a human being make sense of your web service URIs. The use of the semicolon feeds into an obscure idea called matrix URIs (http://www.w3.org/DesignIssues/MatrixURIs.html), a way of defining key-value pairs in URIs without using query variables. Some newer standards, like WADL, offer support for matrix URIs. They’re especially useful if you ever need to put key-value pairs in the middle of a hierarchy.

URIs can become very long, especially when there’s no limit to how deep you can nest the path variables. My web service might let clients name a place using a lot of explicit scoping information: /Earth/North%20Amer ica/USA/California/Northern%20California/San%20Francisco%20Bay %20Area/Sebastopol/...

The HTTP standard doesn’t impose any restrictions on URI length, but real web servers and clients do. For instance, Microsoft Internet Ex- plorer can’t handle URIs longer than 2,083 characters, and Apache won’t respond to requests for URIs longer than 8 KBs. If some of your resources are only addressable given a great deal of scoping information, you may have to accept some of it in HTTP headers, or use overloaded POST and put scoping information in the entity-body.

Map URIs

Now that I’ve designed the URI to a geographic point on a planet, what about the corresponding point on a road map or satellite map? After all, the main point of this service is to serve maps.

Earlier I said I’d expose a resource for every point on a map. For simplicity’s sake, I’m not exposing maps of named places, only points of latitude and longitude. In addition to a set of coordinates or the name of a place, I need the name of the planet and the type of map (satellite map, road map, or whatever). Here are some URIs to maps of planets, places, and points:

• http://maps.example.com/radar/Venus

• http://maps.example.com/radar/Venus/65.9,7.00 • http://maps.example.com/geologic/Earth/43.9,-103.46 Scale

A URI like /satellite/Earth/41,-112 says nothing about how detailed the map should be. I’m going to extend the first path variable so that it doesn’t just specify the type of map: it can also specify the scale. I’ll expose a very small-scale map at /satellite.10/ Earth, a very large-scale map at /satellite.1/Earth, and maps of other scales in be- tween. I’ll choose a sensible default scale: probably a large scale like 2. Here are some possible URIs for the same map at different scales:

• /satellite.10/Earth/41,-112: 1:24,000; 2,000 feet to the inch. A map for hiking or prospecting. Centered on 41°N 112°W on Earth, this map would show the banks of Utah’s Great Salt Lake.

• /satellite.5/Earth/41,-112: 1:250,000; 4 miles to the inch. The scale of a highway map. Centered on 41°N 112°W, this map would show the northern suburbs of Salt Lake City.

• /satellite.1/Earth/41,-112: 1:51,969,000; 820 miles to an inch. (That’s 820 miles/inch at the equator. At this scale, the curvature of the earth distorts the scale of a 2D map.) The scale of a world map. Centered on 41°N 112°W, this map would show much of Utah and surrounding states.

The scale affects not only the natural size of the map in pixels, but which features are shown. A small town would be represented in fair detail on a map at scale 10, but would only be a point at scale 5 if it showed up at all.

How did I decide that scale 1 would be a large-scale map, and scale 10 would be a small- scale map? Why not the reverse? I used a common technique for URI design. I exag- gerated the decision I was making, figured out how the generalized situation should work, and then scaled my decision back down.

Maps can always get more detailed, but there’s a limit how small they can get.#If I decide to acquire some new data for my map service, I’d never buy a map that shows the world in less detail than the world map at scale 1. There’d be no point. However, it’s quite possible that I’ll find maps that are more detailed than the one at scale 10. When I find those maps, I can make them available through my service and assign them scales of 11, 12, and so on. If I’d assigned the most detailed map a scale of 1, I’d have to assign scales of 0, –1, and so on to any new maps. The URIs would look strange. This means larger numbers make good URIs for more detailed maps. I may never ac- tually get those more detailed maps, but thinking about them revealed a truth about my URI design.

In document RESTful Web Services (Page 144-147)