How to add a REST API endpoint

Overview

This guide explains how to add a REST API endpoint to a PlentyONE plugin. REST endpoints allow your plugin to expose data and actions to the PlentyONE frontend or other services over HTTP. You may want to add an endpoint, for example, to retrieve plugin-specific data from the shop without a full page reload, or to accept data submitted by a form.

Before you start

Before you add a REST API endpoint, ensure:

  • Your plugin has a ServiceProvider class registered in plugin.json.

  • Your plugin has a RouteServiceProvider class registered in the ServiceProvider.

  • You are familiar with the PlentyONE plugin file structure.

Add a REST API endpoint

Adding a REST API endpoint involves three steps: creating the resource class that handles the request, registering the route in the route service provider, and verifying the endpoint works.

Create the resource class

A resource class handles the HTTP request and returns a response. It extends ApiResource, which provides access to the incoming Request and the ApiResponse helper.

  1. Create a new PHP file in your plugin’s src/Api/Resources/ directory.

    Name the file after the resource your endpoint represents. For example, `ToDoResource.php`.
  2. Add the following code to the file:

    ToDoList/src/Api/Resources/ToDoResource.php
    <?php
    
    namespace ToDoList\Api\Resources;
    
    use Plenty\Plugin\Http\Response;
    use Plenty\Plugin\Http\Request;
    use Plenty\Plugin\Controller;
    use ToDoList\Contracts\ToDoRepositoryContract;
    
    class ToDoResource extends Controller
    {
        protected $response;
        protected $request;
        private $toDoRepo;
    
        public function __construct(
            Request $request,
            Response $response,
            ToDoRepositoryContract $toDoRepo
        ) {
            $this->request  = $request;
            $this->response = $response;
            $this->toDoRepo = $toDoRepo;
        }
    
        /**
         * Return all tasks for the current user.
         */
        public function index(): Response
        {
            $tasks = $this->toDoRepo->getToDoList();
            return $this->response->json($tasks, 200);
        }
    
        /**
         * Create a new task.
         */
        public function store(): Response
        {
            $task = $this->toDoRepo->createTask($this->request->all());
            return $this->response->json($task, 201);
        }
    }

    The index() method responds to HTTP GET requests and returns all tasks for the current user. The store() method responds to HTTP POST requests and creates a new task.

    If your plugin reuses the ApiResource and ApiResponse classes from another plugin (such as IO), extend ApiResource instead of Controller and use $this→response→create($data, ResponseCode::OK) to build the response.

Register the route

Routes are registered in the RouteServiceProvider using the ApiRouter.

  1. Open your plugin’s RouteServiceProvider file (src/Providers/ToDoRouteServiceProvider.php).

  2. Add the ApiRouter parameter to the map() method signature and register the route using $api→version():

    ToDoList/src/Providers/ToDoRouteServiceProvider.php
    <?php
    
    namespace ToDoList\Providers;
    
    use Plenty\Plugin\RouteServiceProvider;
    use Plenty\Plugin\Routing\ApiRouter;
    use Plenty\Plugin\Routing\Router;
    
    class ToDoRouteServiceProvider extends RouteServiceProvider
    {
        public function map(Router $router, ApiRouter $api): void
        {
            // Page routes
            $router->get('todo', 'ToDoList\Controllers\ContentController@showToDo');
            
            // REST API routes
            $api->version(['v1'], ['namespace' => 'ToDoList\Api\Resources'], function (ApiRouter $api) {
                $api->get('todo/tasks', 'ToDoResource@index');
                $api->post('todo/tasks', 'ToDoResource@store');
            });
        }
    }

    The first argument to $api→get() is the URL path of the endpoint, relative to the API base URL. The second argument references the resource class and method to call, in the format ClassName@methodName.

    Only REST routes registered via ApiRouter are accessible to external services. Page routes registered via Router are intended for browser navigation and are not accessible outside the LTS shop context. If you want another service to consume your endpoint over HTTP, including PlentyONE Shop, it must be registered as a REST route.
    Page routes have to be prefixed with a language code (e.g. en/todo) to work correctly in a multilingual shop. Routes without a prefix are available in the default language. REST API routes are independent of the language prefix.
  3. Ensure your RouteServiceProvider is registered in your ServiceProvider. In the register() method of ToDoServiceProvider.php, confirm the following line is present:

    $this->getApplication()->register(ToDoRouteServiceProvider::class);

Verify the endpoint

  1. Build and deploy your plugin in the PlentyONE back end.

  2. Send a GET request to the tasks endpoint. The URL follows this pattern:

    https://{your-domain}/rest/todo/tasks

    Replace {your-domain} with your PlentyONE system domain.

  3. Confirm that the response returns HTTP status 200 and the expected JSON body.

    If the endpoint returns a 404 error, check that the route is registered correctly in the RouteServiceProvider and that the RouteServiceProvider is registered in the ServiceProvider. If the endpoint returns a 500 error, check the PlentyONE log for PHP errors in your resource class.