From e8563e530b0a9a1060cc0df84d453cd560a76e83 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20K=C3=B6gl?= Date: Sat, 25 May 2013 21:33:26 +0200 Subject: [PATCH] various updates to API 3 draft --- doc/api/reference/events.rst | 34 +------ doc/api/reference/general.rst | 35 ++++++- doc/api/reference/index.rst | 1 + doc/api/reference/prepare.rst | 59 ++++++++++++ doc/api/reference/subscriptions.rst | 176 ++++++++++++++++++++++++++++-------- 5 files changed, 231 insertions(+), 74 deletions(-) create mode 100644 doc/api/reference/prepare.rst diff --git a/doc/api/reference/events.rst b/doc/api/reference/events.rst index b1074c2c..4ac37d50 100644 --- a/doc/api/reference/events.rst +++ b/doc/api/reference/events.rst @@ -188,38 +188,8 @@ Response :: } -Response is being prepared :: - - 203 Found / 202 See Other - Link: /user//events/response/ - - -The server is preparing the result at the specified resource. The client should -try to fetch the data from the given URLs. :: - - GET /user//events/ - 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 diff --git a/doc/api/reference/general.rst b/doc/api/reference/general.rst index e91e5c37..9b2166e8 100644 --- a/doc/api/reference/general.rst +++ b/doc/api/reference/general.rst @@ -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: "", + code: "" } +In ``field`` a `JSON Pointer `_ 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" + } diff --git a/doc/api/reference/index.rst b/doc/api/reference/index.rst index a1399211..951b3b94 100644 --- a/doc/api/reference/index.rst +++ b/doc/api/reference/index.rst @@ -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 index 00000000..b505a556 --- /dev/null +++ b/doc/api/reference/prepare.rst @@ -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/ + + +Prepared Responses +------------------ + +The server can indicate a prepared response in the following way. :: + + 303 See Other + Link: /response/ + +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/ + 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. diff --git a/doc/api/reference/subscriptions.rst b/doc/api/reference/subscriptions.rst index 01d329c6..c73c8c59 100644 --- a/doc/api/reference/subscriptions.rst +++ b/doc/api/reference/subscriptions.rst @@ -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//device//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: /device//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: /device//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: /device//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//device//subscriptions Content-Type: application/json - 200 Found - Link: /device//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//subscriptions Content-Type: application/json - 200 Found + +Response +^^^^^^^^ + +The podcasts correspond to the :ref:`podcast-type` type. :: + + 200 OK Link: /device//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//device//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//device//subscriptions?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: /device//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`). -- 2.11.4.GIT