Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Documentation/Filtering/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ Filters gives possibility to customize SQL query used to receive results in ``GE
{
}

``persistence.storagePid`` limits records of collection operations only. Item operations (``/{id}``) load a record from any page, see :ref:`storage pages <security_storage-pid>`.

It is possible to configure filters only for whole resource. That means filters are available for all ``GET`` collection operations within this resource. It is not possible (yet) to configure filters only for specific operations.
There are few build-in filters. See the next pages.

Expand Down
51 changes: 44 additions & 7 deletions Documentation/GettingStarted/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,35 @@ Getting started
What does it do
================

T3api extension provides easy configurable and customizable REST API for your Extbase models.
It allows to configure whole API functionality with annotations for classes, properties and methods.
T3api provides a configurable and customizable REST API for Extbase models. API resources, their operations, filters
and access rules are configured with annotations on the model class (or on a class extending a model of another
extension, see :ref:`integration`), output of the models with annotations or YAML serializer metadata.

Most of configuration options is based on `API Platform <https://api-platform.com>`_ to make it easier to use for
developers experienced in this awesome framework.
Most configuration options follow `API Platform <https://api-platform.com>`__, so they are familiar to developers who
know this framework.

T3api comes with partial support of `JSON-LD <https://json-ld.org/>`__ and `Hydra <http://www.hydra-cg.com/>`__,
which allows to build smart frontend applications with auto-discoverability capabilities.
Responses use `JSON-LD <https://json-ld.org/>`__ and `Hydra <https://www.hydra-cg.com/>`__ (partial support), which
allows frontend applications to discover resources, filters and pagination from the responses.


Installation
============

T3api supports TYPO3 12.4, 13 and 14 (PHP 8.1 or higher). Run
Supported versions:

.. list-table::
:header-rows: 1

* - TYPO3
- PHP
* - 12.4
- 8.1 - 8.4
* - 13.4
- 8.2 - 8.5
* - 14
- 8.2 - 8.5

Run

.. code-block:: bash

Expand Down Expand Up @@ -119,3 +134,25 @@ After flushing caches the items are available under ``https://example.com/_api/i
* | Single news:
| `https://14.t3api.ddev.site/_api/news/news/1 <https://14.t3api.ddev.site/_api/news/news/1>`__
|

.. _getting-started_backend-module:

Backend module
==============

Backend module **Web API** shows the API of a site in `Swagger UI <https://swagger.io/tools/swagger-ui/>`__ - all
resources and operations with their parameters, filters and response schemas, generated as OpenAPI specification from
the configuration of the API resources. Select the site in the module header. The site needs the
:ref:`route enhancer <route-enhancer>`, otherwise the module shows an error message.

Backend users need access to the module (admins have it by default).

.. important::

"Try it out" in Swagger UI sends real requests to the API of the selected site - ``POST``, ``PATCH``, ``PUT`` and
``DELETE`` change and delete records. The browser sends the requests with its cookies of the API domain, so
:ref:`security <security>` expressions see the frontend or backend user logged in on that domain.

The backend Content Security Policy of the module allows requests to the domains of all sites with the t3api route
enhancer. Swagger UI does not use the online validator of swagger.io, so the URL of the specification is not sent
outside of the TYPO3 instance.
18 changes: 18 additions & 0 deletions Documentation/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,24 @@ If you find an error or something is missing, please: `Report a Problem
<https://github.com/sourcebroker/t3api/issues/new>`__.


T3api provides a REST API for Extbase models. API resources, their operations and filters are configured with
annotations on the model class (or on a class extending a model of another extension, see :ref:`integration`), output
with serializer metadata in annotations or :ref:`YAML <serialization_yaml-metadata>`. Configuration options follow
`API Platform <https://api-platform.com>`__ and responses use `JSON-LD <https://json-ld.org/>`__ /
`Hydra <https://www.hydra-cg.com/>`__ format.

Overview
========

- :ref:`Operations <operations>` - ``GET``, ``POST``, ``PATCH``, ``PUT`` and ``DELETE`` for Extbase models, :ref:`slug fields <operations_slugs>` generated according to TCA.
- :ref:`Filtering <filtering>` and :ref:`pagination <pagination>` of collections, :ref:`ordered UIDs filter <filtering_ordered-uids-filter>` for collections in externally resolved order.
- :ref:`Serialization <serialization>` - output per operation with :ref:`context groups <serialization_context-groups>`, metadata in annotations or :ref:`YAML <serialization_yaml-metadata>`, typolinks, processed images and file references.
- :ref:`Security <security>` - access to operations and filters controlled with expressions.
- :ref:`Response cache <response-cache>` - opt-in cache of ``GET`` responses with tag-based invalidation.
- :ref:`Multilanguage <multilanguage>`, :ref:`file upload <handling_file_upload>`, :ref:`cascade persistence <handling_cascade_persistence>` of relations and :ref:`CORS <cors>`.
- :ref:`Backend module <getting-started_backend-module>` with Swagger UI - OpenAPI documentation of the API and a client to test it.
- :ref:`Customization <customization>` and :ref:`events <events>` to change the behaviour.

**Table of Contents**

.. toctree::
Expand Down
1 change: 1 addition & 0 deletions Documentation/Miscellaneous/Changelog/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Changelog
- Use event request when enriching page cache identifier. [`commit <https://github.com/sourcebroker/t3api/commit/46ab141>`__]
- Delegate to ``Typo3ConditionFunctionsProvider`` instead of extending it. [`commit <https://github.com/sourcebroker/t3api/commit/4442dce>`__]
- Add PHPStan 2 compatibility, rector, PHPUnit attributes. [`commit <https://github.com/sourcebroker/t3api/commit/80ce99b>`__]
- Documentation: ``storagePid`` limits only collection operations, item operations need ``security``. See :ref:`storage pages <security_storage-pid>`.
- Documentation: real examples for TYPO3 14 testing instance, new pages for pagination, security, serialization, integration and file upload.

4.1.3
Expand Down
52 changes: 52 additions & 0 deletions Documentation/Security/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,58 @@ If an expression returns ``false``, the operation is not processed and the respo

``object`` exists only in item operations and in ``security_post_denormalize``. Collection operations (``GET`` and ``POST`` on a collection) do not have it in ``security`` - for collection ``GET`` use filters or your own repository constraints to limit records, for ``POST`` use ``security_post_denormalize``.

.. _security_storage-pid:

Storage pages
==============

``storagePid`` in ``persistence`` attributes limits records of collection ``GET`` operations and is the page where new records are stored. It does **not** limit item operations: ``GET``, ``PATCH``, ``PUT`` and ``DELETE`` on ``/{id}`` load the record by its UID from any page, the same as ``findByUid()`` in Extbase. Hidden records, start and end time and frontend user groups are still respected.

When records must be available only on the storage pages of the resource (e.g. one resource per site or client), check the page of the record in ``security`` of every item operation. ``security`` gets the record as stored in the database, also for ``PATCH`` and ``PUT``.

Do not allow to write ``pid``: when an operation sets ``denormalizationContext`` groups, properties without groups (``pid`` too) are not deserialized. A new record is then stored on the first page from ``storagePid``, and ``PATCH`` / ``PUT`` cannot change the page of a record.

.. code-block:: php

/**
* @T3api\ApiResource (
* attributes={
* "persistence"={"storagePid"="3"}
* },
* collectionOperations={
* "get"={"path"="/products"},
* "post"={
* "method"="POST",
* "path"="/products",
* "denormalizationContext"={"groups"={"api_write_product"}},
* },
* },
* itemOperations={
* "get"={
* "path"="/products/{id}",
* "security"="object.getPid() in t3apiOperation.getPersistenceSettings().getStoragePids()",
* },
* "patch"={
* "method"="PATCH",
* "path"="/products/{id}",
* "security"="object.getPid() in t3apiOperation.getPersistenceSettings().getStoragePids()",
* "denormalizationContext"={"groups"={"api_write_product"}},
* },
* "delete"={
* "method"="DELETE",
* "path"="/products/{id}",
* "security"="object.getPid() in t3apiOperation.getPersistenceSettings().getStoragePids()",
* },
* },
* )
*/

``t3apiOperation.getPersistenceSettings().getStoragePids()`` contains the pages from ``storagePid`` only, without subpages of ``recursive`` - list the pages in the expression when you use ``recursive``.

.. important::

``security_post_denormalize`` alone does not limit item operations to the storage pages, as it checks the record with the data from the request. If ``pid`` is writable, check it there in addition to ``security`` and allow ``null``: ``pid`` of a new record (``POST``) and of a replaced record (``PUT``) is ``null`` until the record is stored, unless the request sends it, e.g. ``object.getPid() === null or object.getPid() in [3]``.

Filter security
================

Expand Down
112 changes: 86 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,111 @@
[![Latest Stable Version](https://poser.pugx.org/sourcebroker/t3api/v/stable)](https://extensions.typo3.org/extension/t3api/)
[![Tests](https://img.shields.io/github/actions/workflow/status/sourcebroker/t3api/tests.yml?branch=main&label=Tests&logo=github)](https://github.com/sourcebroker/t3api/actions/workflows/tests.yml)

Supports TYPO3 12.4, 13.4 and 14 on PHP 8.1 - 8.5.
REST API for Extbase models. Resources, operations and filters are configured with annotations on the model class
(or on a class extending a model of another extension), output with serializer metadata in annotations or YAML.
Configuration options follow [API Platform](https://api-platform.com), responses use [JSON-LD](https://json-ld.org/) /
[Hydra](https://www.hydra-cg.com/) format.

| TYPO3 | PHP |
|-------|-----------|
| 12.4 | 8.1 - 8.4 |
| 13.4 | 8.2 - 8.5 |
| 14 | 8.2 - 8.5 |

## Features

- Support for Extbase models with GET, POST, PATCH, PUT, DELETE operations.
- Configuration with classes, properties and methods annotations.
- Built-in filters: boolean, numeric, uid, contain, order, range, distance and text (partial, match against and exact strategies).
- Ordered UIDs filter and query modifiers - return collections in externally resolved order (e.g. from search engine).
- Built-in pagination.
- Opt-in response caching with automatic tag-based invalidation.
- Support for typolinks.
- Support for image processing.
- Support for file uploads (FAL).
- Configurable routing.
- Responses in [Hydra](https://www.hydra-cg.com/) / [JSON-LD](https://json-ld.org/) format.
- Serialization contexts - customizable output depending on routing.
- Easy customizable serialization handlers and subscribers.
- Backend module with Swagger for documentation and real testing.
**Resources and operations**

- `GET`, `POST`, `PATCH`, `PUT` and `DELETE` operations for Extbase models.
- Configurable routing and base path of the API.
- Cascade persistence of relations, including inline (IRRE) relations.
- Slug fields generated according to TCA configuration.
- Multilanguage support (language prefix in URL or `X-Locale` header).

**Collections**

- Built-in filters: boolean, numeric, uid, contain, order, range, distance and search (partial, match against and exact strategies).
- Ordered UIDs filter and query modifiers - collections in externally resolved order (e.g. from a search engine).
- Pagination.

**Output**

- Serialization contexts (groups) - different output for every operation.
- Serializer metadata in annotations or YAML, custom handlers and subscribers.
- Typolinks, processed images and file references.
- File upload to FAL.

**Access and HTTP**

- Access control of operations and filters with expressions (`security`, `security_post_denormalize`).
- CORS configuration.
- Opt-in response cache with automatic tag-based invalidation.

**Developer tools**

- OpenAPI specification and backend module with Swagger UI for documentation and testing of the API.
- Events to customize processing of operations.

## Quick start

```bash
composer require sourcebroker/t3api
```

Add the route enhancer to the `config.yaml` of your site:

```yaml
imports:
- { resource: "EXT:t3api/Configuration/Routing/config.yaml" }
```

Make an API resource from an Extbase model:

```php
use SourceBroker\T3api\Annotation\ApiResource;

/**
* @ApiResource(
* collectionOperations={
* "get"={"path"="/items"},
* },
* itemOperations={
* "get"={"path"="/items/{id}"},
* },
* )
*/
class Item extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
{
}
```

After flushing caches the items are available under `https://example.com/_api/items` and
`https://example.com/_api/items/1`.

## Documentation

Read the docs at https://docs.typo3.org/p/sourcebroker/t3api/main/en-us/
https://docs.typo3.org/p/sourcebroker/t3api/main/en-us/

## Take a look and test
## Local test instance

After cloning repo you can run:
After cloning the repository run:

```bash
ddev restart && ddev composer install
ddev ci 14
```

to install local integration test instance. Local instance is available at https://14.t3api.ddev.site/
(login to backend with `admin` / `Password1!` credentials).

At frontend part you can at once test REST API responses for ext news:
It installs a TYPO3 14 instance at https://14.t3api.ddev.site/ (backend login `admin` / `Password1!`) with
`EXT:news` records exposed as API resources, e.g.:

- https://14.t3api.ddev.site/_api/
- https://14.t3api.ddev.site/_api/news/news
- https://14.t3api.ddev.site/_api/news/news/1
- https://14.t3api.ddev.site/_api/news/categories
- etc

You can also run Postman test with `ddev composer ci:tests:postman` command or full test suite with `ddev composer ci`.
Postman is doing full CRUD test with category and news (with image).
Run the Postman tests (full CRUD of news and categories, including image upload) with
`ddev composer ci:tests:postman`, or the full test suite with `ddev composer ci`.

## Development

If you want to help with development take a look at https://docs.typo3.org/p/sourcebroker/t3api/main/en-us/Miscellaneous/Development/Index.html
See https://docs.typo3.org/p/sourcebroker/t3api/main/en-us/Miscellaneous/Development/Index.html
Loading
Loading