============
HTTP Methods
============

Resource Registry is a pure RESTful service. It uses standard HTTP Methods to perform a listing of 
collections and CRUD (Create Read Update Delete) operations on instances.


.. table::

  +--------------+-------------+----------------------------------------+---------------------+--------+------------+
  |  Operation   | HTTP Method | URL                                    | Success HTTP Status |  Safe  | Idempotent |
  +==============+=============+========================================+=====================+========+============+
  | Supported    | OPTIONS     | /{collection}                          | 204 No Content      |   Y    |     Y      |
  | HTTP Methods |             |                                        | [#allow]_           |        |            |
  +--------------+-------------+----------------------------------------+---------------------+--------+------------+
  | List         | GET         | /{collection}                          | 200 OK              |   Y    |     Y      |
  +--------------+-------------+----------------------------------------+---------------------+--------+------------+
  | Count        | GET         | /{collection}?count=true               | 200 OK              |   Y    |     Y      |
  +--------------+-------------+----------------------------------------+---------------------+--------+------------+
  | Exists       | HEAD        | /{collection}                          | 204 No Content      |   Y    |     Y      |
  +--------------+-------------+----------------------------------------+---------------------+--------+------------+
  | Create       | POST        | /{collection}                          | 201 Created         |   N    |     N      |
  +--------------+-------------+----------------------------------------+---------------------+--------+------------+
  | Supported    | OPTIONS     | /{collection}/{instance-id}            | 204 No Content      |   Y    |     Y      |
  | HTTP Methods |             |                                        | [#allow]_           |        |            |
  +--------------+-------------+----------------------------------------+---------------------+--------+------------+
  | Exist        | HEAD        | /{collection}/{instance-id}            | 204 No Content      |   Y    |     Y      |
  +--------------+-------------+----------------------------------------+---------------------+--------+------------+
  | Read         | GET         | /{collection}/{instance-id}            | 200 OK              |   Y    |     Y      |
  +--------------+-------------+----------------------------------------+---------------------+--------+------------+
  | Update       | PUT         | /{collection}/{instance-id}            | 200 OK              |   N    |     Y      |
  +--------------+-------------+----------------------------------------+---------------------+--------+------------+
  | Patch        | PATCH       | /{collection}/{instance-id}            | 200 OK              |   N    |     Y      |
  +--------------+-------------+----------------------------------------+---------------------+--------+------------+
  | Delete       | DELETE      | /{collection}/{instance-id}            | 204 No Content      |   N    |  N [#del]_ |
  +--------------+-------------+----------------------------------------+---------------------+--------+------------+
  | Purge        | DELETE      | /{collection}/{instance-id}?purge=true | 204 No Content      |   N    |  N [#del]_ |
  +              +-------------+----------------------------------------+---------------------+--------+------------+
  |              | PURGE       | /{collection}/{instance-id}            | 204 No Content      |   N    |  N [#del]_ |
  +--------------+-------------+----------------------------------------+---------------------+--------+------------+

.. [#allow] Supported HTTP Methods in **Allow** HTTP Header
  
.. [#del] DELETE has been defined as idempotent.
  
  *Allamaraju* [#Allamaraju]_ argues that DELETE idempotency should be accomplished client-side.
  The server should inform the client if the delete operation succeeded because the resource was deleted or it was 
  not found, i.e., **404 Not Found** error is suggested instead of **204 No Content**.
  The latter situation should be treated as idempotent by the client.
  
  We share the same vision. For this reason, Resource Registry does not provide server-side idempotency for 
  DELETE and PURGE operations.

.. [#Allamaraju] Allamaraju S. RESTful Web Services Cookbook: Solutions for Improving Scalability and Simplicity. 
  O'Reilly. first ed. 2010
 
 
About URL
=========

The presented URL uses the following convention:

* **{collection}** is the plural name of the entity type;
* **{instance-id}** is an identification that enables univocally identifying the instance in the collection.


About Safety and Idempotency properties
=======================================


* A method is *Safe* if it does not produce any side effects.
  "This does not prevent an implementation from including behaviour that is potentially harmful, 
  that is not entirely read-only, or that causes side effects while invoking a safe method"
  `<https://tools.ietf.org/html/rfc7231#section-4.2.1>`_;
* A method is *Idempotent* if the same operation repeated multiple times has the same side effect as 
  using it one time.
  "repeating the request will have the same intended effect, even if the original request succeeded, 
  though the response might differ"
  `<https://tools.ietf.org/html/rfc7231#section-4.2.2>`_.

You can find more information about HTTP Methods at `<https://restfulapi.net/http-methods/>`_

Uncommon HTTP Methods
=====================

* PATCH method allows to perform a differential update (i.e. an update which provides only the 
  differences and not the whole new representation);
* PURGE method is not a standard but is widely used in services that require this action
  (e.g. `Varnish <https://varnish-cache.org/docs/3.0/tutorial/purging.html>`_, 
  `Squid <https://wiki.squid-cache.org/SquidFaq/OperatingSquid#How_can_I_purge_an_object_from_my_cache.3F>`_).
  Resource Registry provides support for this method, but to support a wider range of clients, it 
  also provides the Purge action via *DELETE* with the additional get parameter ``purge=true``.


====================
Content-Type
====================

Any request must contain an indication of the interesting content type.

The client must specify the **Accept** HTTP Header for any operation returning a result. 

.. code-block:: rest

  Accept: application/json

For any operation sending content to the service, it is necessary to specify the **Content-Type** HTTP Header.

.. code-block:: rest

  Content-Type: application/json

The service accepts and returns only JSON objects.

==================
Status Codes
==================

The service returns standard HTTP status codes:

**Success Codes:**
- ``200 OK``: Request successful, data returned;
- ``201 Created``: Resource created successfully;
- ``204 No Content``: Operation successful, no data returned (e.g., DELETE).

**Client Error Codes:**
- ``400 Bad Request``: Invalid request format or parameters;
- ``401 Unauthorized``: Missing or invalid authentication token;
- ``403 Forbidden``: Insufficient permissions for the operation;
- ``404 Not Found``: Requested resource does not exist;
- ``405 Method Not Allowed``: The used HTTP method is not supported for the requested URL;
- ``409 Conflict``: The request could not be completed due to a conflict with the current state of the target resource.

**Server Error Codes:**
- ``500 Internal Server Error``: Unexpected server error;
- ``503 Service Unavailable``: Service temporarily unavailable.

You can find a complete list of HTTP Status at `<https://httpstatuses.com/>`_ or 
`<https://httpstatuses.io/>`_

If you get a *500 Internal Server Error*, please report it in the `gCube ticketing system 
<https://support.d4science.org>`_. 

Please use this checklist before reporting an error:

* Replicate the request;
* The failure could be temporal due to a network error, a server issue, and many other temporal issues. 
  For this reason, please retry the request after a certain amount of time before reporting the issue;
* indicate how to replicate the error;
* indicate the time when the error occurred (this simplifies identifying the issue).
