various updates to API 3 draft
authorStefan Kögl <stefan@skoegl.net>
Sat, 25 May 2013 19:33:26 +0000 (25 21:33 +0200)
committerStefan Kögl <stefan@skoegl.net>
Sat, 25 May 2013 19:33:26 +0000 (25 21:33 +0200)
doc/api/reference/events.rst
doc/api/reference/general.rst
doc/api/reference/index.rst
doc/api/reference/prepare.rst [new file with mode: 0644]
doc/api/reference/subscriptions.rst

index b1074c2..4ac37d5 100644 (file)
@@ -188,38 +188,8 @@ Response ::
     }
 
 
-Response is being prepared ::
-
-    203 Found / 202 See Other
-    Link: /user/<username>/events/response/<id>
-
-
-The server is preparing the result at the specified resource. The client should
-try to fetch the data from the given URLs. ::
-
-    GET /user/<username>/events/<id>
-    Content-Tpe: application/json
-
-
-A 404 might be returned before the data is ready. The client may retry after
-xxx seconds. ::
-
-    404 Not Found
-
-
-When the data is ready, 200 will be returned ::
-
-    200 OK
-    Content-Tpe: application/json
-
-    TODO: body...
-
-
-When the data is no longer available, a 410 is returned. ::
-
-    410 Gone
-
-In this case the client SHOULD retry with the previous ``since`` value.
+The server can also return a prepared response (see
+:ref:`prepared-response-api`).
 
 A successful response indicates a timeframe (between ``since`` and
 ``timestamp``) for which events have been retrieved. When using
index e91e5c3..9b2166e 100644 (file)
@@ -57,18 +57,25 @@ All responses are valid JSON (unless otherwise stated).
 Error messages
 --------------
 
-The response could look like ::
+An error response looks like ::
 
     { message: "message", errors: [...] }
 
-Errors could look like this ::
+The ``errors`` array contains objects with the following information ::
 
     {
-        resource: "",
-        field: "",
-        code: ""
+        field: "<JSON Pointer to field>",
+        code: "<error code>"
     }
 
+In ``field`` a `JSON Pointer <http://tools.ietf.org/html/rfc6901>`_ to the
+problematic field in the request is provided. The ``code`` describes the actual
+error. The following error codes are defined:
+
+* ``ìnvalid_url``: The provided values is not a valid URL.
+
+Error codes may be added on demand. Clients should therefore expect and accept
+arbitrary string values.
 
 
 Redirects
@@ -127,3 +134,21 @@ the results wrapped in a JSON function. This is typically used when browsers
 want to embed content received from the API in web pages by getting around
 cross domain issues. The response includes the same data output as the regular
 API, plus the relevant HTTP Header information.
+
+
+Resource Types
+--------------
+
+.. _podcast-type:
+
+Podcast
+^^^^^^^
+
+A podcast is represented as a JSON object containing at least an ``url``
+member. ::
+
+    {
+        url: "http://example.com/podcast.rss",
+        title: "Cool Podcast",
+        logo: "http://example.com/podcast-logo.png"
+    }
index a139921..951b3b9 100644 (file)
@@ -30,3 +30,4 @@ integrating gpodder.net into podcasting applications.
    events
    podcastlists
    settings
+   prepare
diff --git a/doc/api/reference/prepare.rst b/doc/api/reference/prepare.rst
new file mode 100644 (file)
index 0000000..b505a55
--- /dev/null
@@ -0,0 +1,59 @@
+.. _prepared-response-api:
+
+Prepared Response API
+=====================
+
+This API is used by other parts of the API. It is not supposed to be initiated
+by clients directly.
+
+Some requests might require the server to prepare a response. This process can
+take longer than common request timeouts.
+
+In such cases, the server will provide a URL from which the response can be
+retrieved.
+
+
+Resources
+---------
+
+The Prepared Response API defines the following resources ::
+
+ /response/<id>
+
+
+Prepared Responses
+------------------
+
+The server can indicate a prepared response in the following way. ::
+
+    303 See Other
+    Link: /response/<id>
+
+Please note that any URL might be used in the ``Link`` header.
+
+The server is preparing the result at the specified resource. The client should
+try to fetch the data from the given URLs. ::
+
+    GET /response/<id>
+    Content-Tpe: application/json
+
+
+A status code 404 is returned before the data is ready. The client may retry
+after the given number of seconds. ::
+
+    404 Not Found
+    Retry-After: 120
+
+
+When the data is ready, 200 will be returned ::
+
+    200 OK
+    Content-Tpe: application/json
+
+    body
+
+When the data is no longer available, a 410 is returned. ::
+
+    410 Gone
+
+In this case the client SHOULD retry the previous request.
index 01d329c..c73c8c5 100644 (file)
@@ -6,9 +6,6 @@ Subscriptions API
 The subscriptions API is used to manage the podcast subscriptions of a client
 device.
 
-TODO: what to do with not-accepted (invalid) podcasts (eg feed URLs that are
-invalid URLs)?
-
 
 Resources
 ---------
@@ -22,100 +19,205 @@ The Subscriptions API defines the following resources ::
 Subscription Upload
 -------------------
 
-Upload the subscriptions for a device ::
+Clients can upload the podcast subscriptions for a device to replace any
+existing subscriptions.
+
+
+Request
+^^^^^^^
+
+The client sends an object containing all current subscriptions for the
+device. ::
 
  PUT /user/<username>/device/<device-id>/subscriptions
- Content-Tpe: application/json
+ Content-Type: application/json
+
+ {
+    podcasts: [
+        { url: "http://example.com/podcast.rss" },
+        { url: "http://podcast.com/episodes.xml" }
+    ]
+ }
 
- TODO: specify body
 
+Response
+^^^^^^^^
 
 The server can respond with the following status codes.
 
-When a new device has been created ::
+If a ``Link`` header with ``rel=changes`` is provided, this URL can be used to
+retrieve changes to the subscriptions since the respective response (see
+:ref:`subscription-change-download`)
+
+If a new device has been created ::
 
  201 Created
  Link: <https://api.gpodder.net/user/<username>/device/<device-id>/subscription?since=0>; rel=changes
- ...
 
+ no body
 
-When the subscriptions have been processed immediatelly ::
+
+If the subscriptions have been processed immediatelly ::
 
  204 No Content
  Link: <https://api.gpodder.net/user/<username>/device/<device-id>/subscription?since=1234>; rel=changes
- ...
+
+ no body
 
 
-When the subscriptions have been accepted for later processing ::
+If the subscriptions have been accepted for later processing ::
 
  202 Accepted
- Link: <https://api.gpodder.net/user/<username>/device/<device-id>/subscription?since=1234>; rel=changes
- ...
- TODO: return change download address here?
 
+ no body
 
-Any status code >= 200 and < 300 should be considered a success.
+No change download address is provided in this case, as is is not yet known at
+the time of the response. If the client needs to know the current
+subscriptions, it should follow up by a request to download the subscriptions.
 
-TODO: specify body?
+If invalid podcast information is provided (eg an invalid feed URL), the whole
+request will be rejected. ::
+
+ 400 Bad Request
+ Content-Type: application/json
+
+ {
+   "message": "Invalid podcast URL",
+   "errors": [
+     {
+       "field": "/podcasts/1",
+       "code": "invalid_url"
+     }
+   ]
+ }
 
 
 Subscription Download
 ---------------------
 
+Clients can download the current subscriptions of a device.
+
+
+Request
+^^^^^^^
+
 Download subscriptions of a device ::
 
  GET /user/<username>/device/<device-id>/subscriptions
  Content-Type: application/json
 
- 200 Found
- Link: <https://api.gpodder.net/user/<username>/device/<device-id>/subscription?since=1234>; rel=changes
- Content-Type: application/json
- Last-Modified: ...
-
- {
-     "add": [{ "url": "..."}, { ...}]
-     "timestamp": 1234,
- }
 
-
-Download all of the users subscriptions ::
+Download all of the user's subscriptions ::
 
  GET /user/<username>/subscriptions
  Content-Type: application/json
 
- 200 Found
+
+Response
+^^^^^^^^
+
+The podcasts correspond to the :ref:`podcast-type` type. ::
+
+ 200 OK
  Link: <https://api.gpodder.net/user/<username>/device/<device-id>/subscription?since=1234>; rel=changes
  Content-Type: application/json
- Last-Modified: ...
 
- TODO: specify body
+ {
+    podcasts: [
+        { podcast1 },
+        { podcast2 }
+    ]
+ }
+
+The changes link is not provided if all subscriptions of a user are requested.
 
 
 Subscription Change Upload
 --------------------------
 
-Upload changes to the subscriptions of a device ::
+Clients can update the current subscriptions of a device by reporting
+subscribed and unsubscribed podcasts.
+
+
+Request
+^^^^^^^
+
+A client can send which podcasts have been subscribed and unsubscribed. ::
 
  POST /user/<username>/device/<device-id>/subscriptions
  Content-Tpe: application/json
 
- TODO: specify body...
+ {
+    subscribe: [
+        { url: "http://example.com/podcast.rss" }
+    ]
+    unsubscribe: [
+        { url: "http://podcast.com/episodes.xml" }
+    ]
+ }
+
+A client MUST NOT upload a change set where both ``subscribe`` and
+``unsubscribe`` are empty.
+
+
+Response
+^^^^^^^^
+
+The server responds with either of the following status codes.
+
+The changes are processed immediatelly. ::
+
+ 200 OK
+ Content-Tpe: application/json
+
+ body according to Subscription Download
 
 
+The changes have been accepted for later processing. ::
+
+ 204 Accepted
+
+ no body
+
+No response body is provided in this case, as it is not yet known.
+
+
+.. _subscription-change-download:
 
 Subscription Change Download
 ----------------------------
 
-Download changes to the subscriptions of a device ::
+Download changes to the subscriptions of a device.
+
+
+Request
+^^^^^^^
+
+The client makes the following request. ::
 
  GET /user/<username>/device/<device-id>/subscriptions?since=<since>
  Content-Tpe: application/json
 
- 200 Found
+
+Response
+^^^^^^^^
+
+The server can response with any of the following status codes.
+
+The changes are returned immediatelly. ::
+
+ 200 OK
  Link: <https://api.gpodder.net/user/<username>/device/<device-id>/subscription?since=1234>; rel=changes
  Content-Type: application/json
- Last-Modified: ...
-
- TODO: specify body...
 
+ {
+    subscribe: [
+        { url: "http://example.com/podcast.rss" }
+    ]
+    unsubscribe: [
+        { url: "http://podcast.com/episodes.xml" }
+    ]
+ }
 
+The server can also return a prepared response (see
+:ref:`prepared-response-api`).