Image of a mountain
REST web service for TYPO3 CMS.
Scroll to content

Resource Type

The Resource Type is an identifier for a model class. It is the first segment of the request path, after alias mapping has been applied.

Sending data

Different "layouts" for sent data are supported by the extension:

Send raw body

curl -X POST \
-H "Content-Type: application/json" \
-d '{
  "property1":"Value 1",
  "property2":"Value 2"
}' \
"http://your-domain.com/rest/..."

Send form-data

curl -X POST \
-H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" \
-d '------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="field1"

Value 1
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="field2"

Value 2
------WebKitFormBoundary7MA4YWxkTrZu0gW--' \
"http://your-domain.com/rest/..."

Send x-www-form-urlencoded

curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'field1=Value 1&field2=Value 2' \
"http://your-domain.com/rest/..."

In a custom Handler implementation the sent data can be retrieved through the request's getSentData() method.

Customize the output of a model

The easiest way to customize the properties exported by your models is through implementing the JsonSerializable interface.

<?php

declare(strict_types=1);

class Person extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
    implements JsonSerializable {

    public function jsonSerialize(): mixed
    {
        return [
            'companyName' => 'the company name'
        ];
    }
}

Add additional headers

# config/sites/{your-site}/settings.yaml or {EXT:my-site-package}/Configuration/Sets/{MySitePackage}/settings.yaml
rest:
    settings:
        responseHeaders:
            Access-Control-Allow-Origin: http://localhost:5173
            Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE

Preprocess input data

The best way to preprocess sent data before saving is to create a custom DataProvider.

Lets assume your extension is in the namespace \Foo\Bar. When you request /foo-bar-model the Object Manager will look for a class called \Foo\Bar\Rest\DataProvider and will use it to fetch and create models (the built in DataProvider \Cundd\Rest\DataProvider\DataProvider is used as fallback).

You can extend the default DataProvider and overwrite prepareModelData().

<?php

declare(strict_types=1);

namespace Foo\Bar\Rest;

class DataProvider extends \Cundd\Rest\DataProvider\DataProvider {
    #[\Override]
    protected function prepareModelData(array $data): array
    {
        // Work with the data
        return $data;
    }
}

How do paths and classes work together?

Paths, Resource Types and the associated classes

Below you find examples of the URL paths (the part after rest/) and the matching class names that will be used:

Path Resource Type Class Repository Data Provider Conf
/cundd-foo-bar cundd-foo-bar \Cundd\Foo\Domain\Model\Bar[] \Cundd\Foo\Domain\Repository\BarRepository \Cundd\Rest\DataProvider\DataProvider a
/cundd-foo-bar/34 cundd-foo-bar \Cundd\Foo\Domain\Model\Bar \Cundd\Foo\Domain\Repository\BarRepository \Cundd\Rest\DataProvider\DataProvider a
/Document/db Document-db \Cundd\Rest\Domain\Model\Document[] \Cundd\Rest\Domain\Repository\DocumentRepository \Cundd\Rest\DataProvider\DocumentDataProvider b
/Document/db/9 Document-db \Cundd\Rest\Domain\Model\Document \Cundd\Rest\Domain\Repository\DocumentRepository \Cundd\Rest\DataProvider\DocumentDataProvider b
/Document/db/a3b Document-db \Cundd\Rest\Domain\Model\Document \Cundd\Rest\Domain\Repository\DocumentRepository \Cundd\Rest\DataProvider\DocumentDataProvider b
/cundd-daa-bar cundd-daa-bar * * \Cundd\Daa\Rest\DataProvider c
/cundd-daa-bar/34 cundd-daa-bar * * \Cundd\Daa\Rest\DataProvider c

*) These classes are not fixed and depend on the custom \Cundd\Daa\Rest\DataProvider.

Paths, methods and the associated actions

Example: A Document Storage

Path Method Class Action Conf
/Document/db GET \Cundd\Rest\Domain\Model\Document[] List all Documents in database 'db' b
/Document/db POST \Cundd\Rest\Domain\Model\Document Create a new Document in database 'db' b
/Document/db DELETE 405 Method Not Allowed b
/Document/db/9 GET \Cundd\Rest\Domain\Model\Document Return the Document with UID or ID 2 in database 'db' b
/Document/db/9 POST \Cundd\Rest\Domain\Model\Document Replace the Document with UID or ID 2 in database 'db' b
/Document/db/9 DELETE \Cundd\Rest\Domain\Model\Document Delete the Document with UID or ID 2 in database 'db' b
/Document/db/9 PATCH \Cundd\Rest\Domain\Model\Document Update the Document with UID or ID 2 in database 'db' b

Configuration

b)

# config/sites/{your-site}/settings.yaml or {EXT:my-site-package}/Configuration/Sets/{MySitePackage}/settings.yaml
rest:
    settings:
        paths:
            cundd-foo-bar:
                path: cundd-foo-bar
                read: allow
                write: allow

c)

# config/sites/{your-site}/settings.yaml or {EXT:my-site-package}/Configuration/Sets/{MySitePackage}/settings.yaml
rest:
    settings:
        paths:
            document-db:
                path: Document-db
                read: allow
                write: allow

d)

Assume the class \Cundd\Daa\Rest\DataProvider exists.

# config/sites/{your-site}/settings.yaml or {EXT:my-site-package}/Configuration/Sets/{MySitePackage}/settings.yaml
rest:
    settings:
        paths:
            cundd-daa-bar:
                path: Cundd-Daa-Bar
                read: allow
                write: allow

Caching

⚠︎ NEVER cache user-specific or personally identifiable information! The cache is shared between requests - even for authenticated requests.

The extension can be configured to cache responses to GET requests. The behaviour is configured for each Resource Type individually:

# config/sites/{your-site}/settings.yaml or {EXT:my-site-package}/Configuration/Sets/{MySitePackage}/settings.yaml
rest:
    settings:
        paths:
            cundd-daa-bar:
                path: cundd-daa-bar
                read: allow
                write: allow
                cacheLifetime: 3600

If cacheLifetime is set to 0, TYPO3's caching framework will cache the response forever.

Additionally, the Expires header can be configured. The resulting value will be the current time + the number of seconds in expiresHeaderLifetime:

# config/sites/{your-site}/settings.yaml or {EXT:my-site-package}/Configuration/Sets/{MySitePackage}/settings.yaml
rest:
    settings:
        paths:
            cundd-daa-bar:
                path: cundd-daa-bar
                read: allow
                write: allow
                cacheLifetime: 3600
                expiresHeaderLifetime: 3600

To apply the same cache configuration for all requests a global fallback can be specified:

# config/sites/{your-site}/settings.yaml or {EXT:my-site-package}/Configuration/Sets/{MySitePackage}/settings.yaml
rest:
    settings:
        cacheLifetime: 3600
        expiresHeaderLifetime: 300

Install TYPO3 and REST in a subdirectory

If the TYPO3 installation is inside a subdirectory the environment variable TYPO3_REST_REQUEST_BASE_PATH has to be set to the subdirectories name.

E.g.: TYPO3 is installed in $DOC_ROOT/dev_install/ and accessed through http://your-domain.com/dev_install/rest/ set TYPO3_REST_REQUEST_BASE_PATH to dev_install.

Internationalization and localization

The start page of your site should be translated. The extension will use it as the context for handling the request.

  • Since version 3.6.0 TYPO3's site handling is supported