The HyperCities API
Davidshepard (Talk | contribs) |
Davidshepard (Talk | contribs) |
||
(2 intermediate revisions by one user not shown) | |||
Line 1: | Line 1: | ||
HyperCities exposes a [http://en.wikipedia.org/wiki/Representational_state_transfer RESTful] API for viewing and editing objects, collections, maps, and cities. In REST, a webservice provides access to “resources”, or data items. Each resource can be accessed at a unique URL. Accessing and editing a resource are accomplished using different HTTP methods such as GET or POST. Each of these resources usually fall into a few different categories, and a web service may have many items in many categories. The last isn’t necessarily part of the formal definition of REST, but it’s a convention used in most RESTful services. | HyperCities exposes a [http://en.wikipedia.org/wiki/Representational_state_transfer RESTful] API for viewing and editing objects, collections, maps, and cities. In REST, a webservice provides access to “resources”, or data items. Each resource can be accessed at a unique URL. Accessing and editing a resource are accomplished using different HTTP methods such as GET or POST. Each of these resources usually fall into a few different categories, and a web service may have many items in many categories. The last isn’t necessarily part of the formal definition of REST, but it’s a convention used in most RESTful services. | ||
− | + | = REST verbs = | |
+ | |||
+ | In REST, a separate HTTP verb (GET, POST, PUT, and DELETE) performs each action. You can probably guess what each one does, except for POST and PUT. There is disagreement on whether POST should create and PUT should update, or vice versa. HyperCities uses the following scheme: | ||
+ | {| | ||
+ | !HTTP Method | ||
+ | !URL | ||
+ | !Description | ||
+ | |- | ||
+ | |GET | ||
+ | |/{resource type} | ||
+ | |search for resources of that type | ||
+ | |- | ||
+ | |GET | ||
+ | |/{resource_type}/{id} | ||
+ | |get one resource | ||
+ | |- | ||
+ | |POST | ||
+ | |/{resource_type} | ||
+ | |create a new resource of that type | ||
+ | |- | ||
+ | |POST | ||
+ | |/{resource_type}/{id} | ||
+ | |update an existing resource | ||
+ | |- | ||
+ | |DELETE | ||
+ | |/{resource_type}/{id} | ||
+ | |delete that resource | ||
+ | |} | ||
+ | |||
+ | We do not use PUT because PUT is difficult to implement, especially in a browser, and its functions can be equally implemented by POST. | ||
+ | |||
+ | When you update a resource, you must supply all attributes of the resource for every request. Missing attributes will be erased or set to default values if they are not supplied, or result in validation errors. Think about each resource as a file, not a collection of attributes: you always have to send the whole back, not just the changes. | ||
+ | There are different ways of specifying the format in which data should be returned in REST. Some services use Accept headers; others user file extensions (e.g. /maps/1.json). Both have tradeoffs. HyperCities exclusively uses extensions for simplicity and the fact that it uses some nonstandard formats, like KML, which have to be produced for geobrowsers that might not send correct headers. It involves less debugging to give your users a URL to copy and paste that is guaranteed to return the correct format. | ||
+ | |||
+ | = Resource types = | ||
+ | HyperCities has three kinds of resources: rich objects, collections, and maps. | ||
* '''[[Rich Objects API|Rich objects]]''' are any kind of item you see on the map, with the exception of historical maps; maps are distinguished from rich objects because all major mapping APIs (Google Maps, Google Earth, OpenLayers, Leaflet, Polymaps, and the like) differentiate between clickable items on the map, and additional tiles overlaid on the map. | * '''[[Rich Objects API|Rich objects]]''' are any kind of item you see on the map, with the exception of historical maps; maps are distinguished from rich objects because all major mapping APIs (Google Maps, Google Earth, OpenLayers, Leaflet, Polymaps, and the like) differentiate between clickable items on the map, and additional tiles overlaid on the map. | ||
+ | * '''[[Collections API|Collections]]''' are ordered sets of rich objects, which are frequently used to form narratives. While collections and rich objects are accessed through different URLs (/objects and /collections, respectively), they are stored in the same database tables as they are part of the same hierarchy--an object belongs to one (or more) collections, and can contain one or more objects and collections itself (we’ll cover this later). | ||
* '''[[Maps API|Maps]]''' are tiled images overlaid on the main HyperCities map. | * '''[[Maps API|Maps]]''' are tiled images overlaid on the main HyperCities map. | ||
− | |||
− | |||
Rich objects, maps, and collections can be exposed in JSON formats. This JSON format is custom for HyperCities, not a standard like GeoJSON. Rich objects and collections are also available as KML. The details of these formats are all documented in the links above. | Rich objects, maps, and collections can be exposed in JSON formats. This JSON format is custom for HyperCities, not a standard like GeoJSON. Rich objects and collections are also available as KML. The details of these formats are all documented in the links above. | ||
+ | |||
+ | |||
+ | = Response types = | ||
+ | |||
+ | Attempting to create, delete, or update any kind of resource will usually return one of the following responses: | ||
+ | |||
+ | {| | ||
+ | !HTTP Code | ||
+ | !Message | ||
+ | !Meaning | ||
+ | |- | ||
+ | |201 | ||
+ | |Object Created | ||
+ | |The object was successfully created. | ||
+ | |- | ||
+ | |202 | ||
+ | |Object Updated | ||
+ | |Object was successfully updated | ||
+ | |- | ||
+ | |400 | ||
+ | |Bad Request | ||
+ | |Values supplied for the object were either incomplete or invalid. | ||
+ | |- | ||
+ | |401 | ||
+ | |Insufficient Privileges | ||
+ | |The current user is not allowed to edit this resource. (Also, the user may not be logged in.) | ||
+ | |- | ||
+ | |404 | ||
+ | |Not Found | ||
+ | |The object was not found. | ||
+ | |} | ||
+ | |||
+ | = Authentication = | ||
+ | If you create a tool for editing HyperCities objects, then you will need to handle authentication. HyperCities uses OpenID for authentication. HyperCities relies on cookies for authentication, so you will really only be able to create a web front-end for editing HyperCities on the same domain as the back-end. This means you will already have gone through the process of selecting which providers to use and acquiring auth tokens from those providers. HyperCities contains a default OpenID interface, which uses loginOpenId.php for the login interface and loginOidReturn.php for the callback URL. You will probably not want to implement all the different providers; we include MySpace because we have a few legacy accounts created using MySpace logins. | ||
+ | |||
+ | The basic cycle is this: the client opens a separate popup window with loginOpenId.php. This file contains all the logic for selecting a provider and redirecting that window (and only that window) to the correct provider. The provider authenticates the user (if possible) and then returns the user to loginOidReturn.php. loginOidReturn.php updates the user’s session to reflect their logged-in status, sends new users to a registration page (we don’t collect any info from the OID providers), and, once this is complete, calls the HyperCities.user object to reload the session information from the server. Then it closes the window itself. You will probably rename the callback function that updates the session; this is currently in the <script> tag in loginOidReturn.php. This will have to be changed. | ||
+ | |||
+ | The default process should more or less work if your application follows the same assumptions--that you load all data from the server and can reload the session info via AJAX. However, this may not work for you. Depending on how you design the flow of your application, you may want to rethink this process. This process, however, has worked fairly well in the past and made it easy to add new providers. |
Latest revision as of 16:32, 5 June 2013
HyperCities exposes a RESTful API for viewing and editing objects, collections, maps, and cities. In REST, a webservice provides access to “resources”, or data items. Each resource can be accessed at a unique URL. Accessing and editing a resource are accomplished using different HTTP methods such as GET or POST. Each of these resources usually fall into a few different categories, and a web service may have many items in many categories. The last isn’t necessarily part of the formal definition of REST, but it’s a convention used in most RESTful services.
Contents |
REST verbs
In REST, a separate HTTP verb (GET, POST, PUT, and DELETE) performs each action. You can probably guess what each one does, except for POST and PUT. There is disagreement on whether POST should create and PUT should update, or vice versa. HyperCities uses the following scheme:
HTTP Method | URL | Description |
---|---|---|
GET | /{resource type} | search for resources of that type |
GET | /{resource_type}/{id} | get one resource |
POST | /{resource_type} | create a new resource of that type |
POST | /{resource_type}/{id} | update an existing resource |
DELETE | /{resource_type}/{id} | delete that resource |
We do not use PUT because PUT is difficult to implement, especially in a browser, and its functions can be equally implemented by POST.
When you update a resource, you must supply all attributes of the resource for every request. Missing attributes will be erased or set to default values if they are not supplied, or result in validation errors. Think about each resource as a file, not a collection of attributes: you always have to send the whole back, not just the changes. There are different ways of specifying the format in which data should be returned in REST. Some services use Accept headers; others user file extensions (e.g. /maps/1.json). Both have tradeoffs. HyperCities exclusively uses extensions for simplicity and the fact that it uses some nonstandard formats, like KML, which have to be produced for geobrowsers that might not send correct headers. It involves less debugging to give your users a URL to copy and paste that is guaranteed to return the correct format.
Resource types
HyperCities has three kinds of resources: rich objects, collections, and maps.
- Rich objects are any kind of item you see on the map, with the exception of historical maps; maps are distinguished from rich objects because all major mapping APIs (Google Maps, Google Earth, OpenLayers, Leaflet, Polymaps, and the like) differentiate between clickable items on the map, and additional tiles overlaid on the map.
- Collections are ordered sets of rich objects, which are frequently used to form narratives. While collections and rich objects are accessed through different URLs (/objects and /collections, respectively), they are stored in the same database tables as they are part of the same hierarchy--an object belongs to one (or more) collections, and can contain one or more objects and collections itself (we’ll cover this later).
- Maps are tiled images overlaid on the main HyperCities map.
Rich objects, maps, and collections can be exposed in JSON formats. This JSON format is custom for HyperCities, not a standard like GeoJSON. Rich objects and collections are also available as KML. The details of these formats are all documented in the links above.
Response types
Attempting to create, delete, or update any kind of resource will usually return one of the following responses:
HTTP Code | Message | Meaning |
---|---|---|
201 | Object Created | The object was successfully created. |
202 | Object Updated | Object was successfully updated |
400 | Bad Request | Values supplied for the object were either incomplete or invalid. |
401 | Insufficient Privileges | The current user is not allowed to edit this resource. (Also, the user may not be logged in.) |
404 | Not Found | The object was not found. |
Authentication
If you create a tool for editing HyperCities objects, then you will need to handle authentication. HyperCities uses OpenID for authentication. HyperCities relies on cookies for authentication, so you will really only be able to create a web front-end for editing HyperCities on the same domain as the back-end. This means you will already have gone through the process of selecting which providers to use and acquiring auth tokens from those providers. HyperCities contains a default OpenID interface, which uses loginOpenId.php for the login interface and loginOidReturn.php for the callback URL. You will probably not want to implement all the different providers; we include MySpace because we have a few legacy accounts created using MySpace logins.
The basic cycle is this: the client opens a separate popup window with loginOpenId.php. This file contains all the logic for selecting a provider and redirecting that window (and only that window) to the correct provider. The provider authenticates the user (if possible) and then returns the user to loginOidReturn.php. loginOidReturn.php updates the user’s session to reflect their logged-in status, sends new users to a registration page (we don’t collect any info from the OID providers), and, once this is complete, calls the HyperCities.user object to reload the session information from the server. Then it closes the window itself. You will probably rename the callback function that updates the session; this is currently in the <script> tag in loginOidReturn.php. This will have to be changed.
The default process should more or less work if your application follows the same assumptions--that you load all data from the server and can reload the session info via AJAX. However, this may not work for you. Depending on how you design the flow of your application, you may want to rethink this process. This process, however, has worked fairly well in the past and made it easy to add new providers.