Skip to content

Commit

Permalink
Started to fix unclear statements about OCS and REST
Browse files Browse the repository at this point in the history
Signed-off-by: Christian Wolf <[email protected]>
  • Loading branch information
christianlupus committed Oct 3, 2024
1 parent 162b7b0 commit 71d81da
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 5 deletions.
15 changes: 12 additions & 3 deletions developer_manual/basics/controllers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -732,10 +732,15 @@ The following policy for instance allows images, audio and videos from other dom
OCS
^^^

.. note:: This is purely for compatibility reasons. If you are planning to offer an external API, go for a :doc:`../digging_deeper/rest_apis` instead.
In order to simplify exchange of data between the Nextcloud backend and any client (be it the web frontend or whatever else), the OCS API has been introduced.
Here, JSON and XML responders have been prepared and are installed without additional effort.

In order to ease migration from OCS API routes to the App Framework, an additional controller and response have been added. To migrate your API you can use the **OCP\\AppFramework\\OCSController** base class and return your data in the form of a DataResponse in the following way:
.. note::
The usage of OCS is closely related to the usage of :doc:`../digging_deeper/rest_apis`.
Unless you have a clear use-case, it is advised to use OCS over pure REST.
A more detailed description can be found in :ref:`ocs-vs-rest`.

To use OCS in your API you can use the **OCP\\AppFramework\\OCSController** base class and return your data in the form of a **DataResponse** in the following way:

.. code-block:: php
Expand All @@ -759,7 +764,7 @@ In order to ease migration from OCS API routes to the App Framework, an addition
The format parameter works out of the box, no intervention is required.

In order to make routing work for OCS routes you need to add a separate 'ocs' entry to the routing table of your app.
In order to make routing work for OCS routes you need to add a separate 'ocs' entry to the routing table in ``appinf/routes.php`` of your app.
Inside these are normal routes.

.. code-block:: php
Expand All @@ -778,6 +783,10 @@ Inside these are normal routes.
Now your method will be reachable via ``<server>/ocs/v2.php/apps/<APPNAME>/api/v1/shares``

.. versionadded:: 29
You can use the attribute ``ApiRoute`` as described in :doc:`Routing <routing>` instead of the entry in ``appinfo/routed.php`` as an alternative.


Handling errors
^^^^^^^^^^^^^^^

Expand Down
69 changes: 67 additions & 2 deletions developer_manual/digging_deeper/rest_apis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ REST APIs

.. sectionauthor:: Bernhard Posselt <[email protected]>

Offering a RESTful API is not different from creating a :doc:`route <../basics/routing>` and :doc:`controllers <../basics/controllers>` for the web interface. It is recommended though to inherit from ApiController and add **@CORS** annotations to the methods so that `web applications will also be able to access the API <https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS>`_.
Offering a RESTful API is not different from creating a :doc:`route <../basics/routing>` and :doc:`controllers <../basics/controllers>` for the web interface.
It is recommended though to inherit from ApiController and add **@CORS** annotations to the methods so that `web applications will also be able to access the API <https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS>`_.

.. code-block:: php
Expand Down Expand Up @@ -44,7 +45,8 @@ CORS also needs a separate URL for the preflighted **OPTIONS** request that can
)
Keep in mind that multiple apps will likely depend on the API interface once it is published and they will move at different speeds to react to changes implemented in the API. Therefore it is recommended to version the API in the URL to not break existing apps when backwards incompatible changes are introduced::
Keep in mind that multiple apps will likely depend on the API interface once it is published and they will move at different speeds to react to changes implemented in the API.
Therefore it is recommended to version the API in the URL to not break existing apps when backwards incompatible changes are introduced::

/index.php/apps/myapp/api/1.0/resource

Expand Down Expand Up @@ -79,3 +81,66 @@ To add an additional method or header or allow less headers, simply pass additio
}
}
.. _ocs-vs-rest:

Relation of REST and OCS
------------------------

There is a close relationship between REST APIs and :ref:`OCS <ocscontroller>`.
Both provide a way to transmit data between the backend of the app in the Nextcloud server and some frontend.

The following combinations of attributes might be useful for various scenarios:

#. Plain frontend route: No special attribute related to CSRF or CORS
#. Plain Frontend with CRSF checks disabled: Add the ``#[NoCSRFRequired]`` attribute
#. REST route with CORS enabled: Add the ``#[CORS]`` attribute
#. OCS-based route

There are different ways a clients might interact with your APIs.
These ways depend on your API configuration (what you allow) and on which route the request is finally made.

- *Access from web frontend* means the user is browses the Nextcloud web frontend with a browser.
- *Access from an external app* indicates that the user is not using the normal browser (as logged in) but directly navigates a certain URL.
This can be in a browser tab or an external program (like an Android app or simply a curl command line).
- *Access from external website* means that the user browses some third party web site and *magically* data from your app appears.
Technically, the other website would embed/load/use images, JSON data, or other resources from a URL pointing to the Nextcloud server.

.. list-table:: Comparision of different API types
:header-rows: 1
:align: center

* - Description
- 1 (plain)
- 2 (no CSRF)
- 3 (CORS)
- 4 (OCS)
* - URL prefix (relative to server)
- ``/apps/<appid>/``
- ``/apps/<appid>/``
- ``/apps/<appid>/``
- ``/ocs/v2.php/apps/<appid>/``
* - Access from web frontend
- yes
- yes (CSRF risk)
- yes (CSRF risk)
- yes
* - Access from external app
- --- (CSRF protection blocks)
- yes
- yes
- yes
* - Access from external web page
- ---
- ---
- yes
- yes
* - Transmitted data type
- plain data
- plain data
- plain data
- encapsulated data

As a rule of thumb one can conclude that OCS provides a good way to handle most use cases.
The only exception to this is if you want to provide an API for external usage where you have to comply with an externally defined API scheme.
Here, the encapsulation introduced in OCS might be in your way.

0 comments on commit 71d81da

Please sign in to comment.