PHPackages                             otezvikentiy/json-rpc-api - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. otezvikentiy/json-rpc-api

ActiveSymfony-bundle[API Development](/categories/api)

otezvikentiy/json-rpc-api
=========================

Symfony Json RPC API bundle

5.0-stable(4d ago)42591[1 PRs](https://github.com/OtezVikentiy/symfony-jsonrpc-api-bundle/pulls)MITPHPPHP 8.2.\* || 8.3.\* || 8.4.\* || 8.5.\*CI passing

Since Aug 11Pushed 4d ago2 watchersCompare

[ Source](https://github.com/OtezVikentiy/symfony-jsonrpc-api-bundle)[ Packagist](https://packagist.org/packages/otezvikentiy/json-rpc-api)[ RSS](/packages/otezvikentiy-json-rpc-api/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (1)Dependencies (35)Versions (61)Used By (0)

OtezVikentiy Symfony JSON-RPC API Bundle
========================================

[](#otezvikentiy-symfony-json-rpc-api-bundle)

[English](README.md) · [Русский](README.ru.md)

[![CI](https://github.com/OtezVikentiy/symfony-jsonrpc-api-bundle/actions/workflows/ci.yml/badge.svg)](https://github.com/OtezVikentiy/symfony-jsonrpc-api-bundle/actions/workflows/ci.yml)[![Latest Stable Version](https://camo.githubusercontent.com/3666fa51a519a0232053c8cf0179ab3edf43970787d97dc382b90963ec1687d0/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6f74657a76696b656e7469792f6a736f6e2d7270632d6170692e737667)](https://packagist.org/packages/otezvikentiy/json-rpc-api)[![PHP Version](https://camo.githubusercontent.com/ff3eb1e93b3eec0f62dbe22232e2154cc64ac2295354e0ac604cdeb75ce86461/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e322532302d2d253230382e352d3838393242462e737667)](https://php.net/)[![Symfony Version](https://camo.githubusercontent.com/a9d718583e13fad5b1fbe301cf632f3daa8a7dd6de646cd4f8057f85bf10b5ca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f73796d666f6e792d253545362e34253230253743253743253230253545372e30253230253743253743253230253545382e302d3030303030302e737667)](https://symfony.com/)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](https://opensource.org/licenses/MIT)[![Coverage](https://camo.githubusercontent.com/e36596c71b5317b5bdac63741b8c1ddd03b05ddfe8f864a12802b1e40686b6e1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f7665726167652d39392532352d627269676874677265656e2e737667)](https://github.com/OtezVikentiy/symfony-jsonrpc-api-bundle/actions/workflows/ci.yml)

A Symfony bundle for fast and convenient creation of JSON-RPC 2.0 API applications.

GitHub:

---

Features
--------

[](#features)

- Full [JSON-RPC 2.0](https://www.jsonrpc.org/specification) specification compliance
- Method configuration via PHP 8 attributes (`#[JsonRPCAPI(...)]`)
- HTTP methods support: POST, GET, PUT, PATCH, DELETE
- API versioning (`/api/v1`, `/api/v2`, ...)
- Automatic OpenAPI/Swagger documentation generation
- Pre- and Post-processors (middleware)
- Batch requests
- Built-in request validation
- Role-based access control via Symfony Security
- Binary response support (images, documents)

---

Requirements
------------

[](#requirements)

- PHP 8.2 – 8.5
- Symfony ^6.4 || ^7.0 || ^8.0

---

Installation
------------

[](#installation)

```
composer require otezvikentiy/json-rpc-api
```

Enable the bundle (if not using Symfony Flex):

```
// config/bundles.php
return [
    // ...
    OV\JsonRPCAPIBundle\OVJsonRPCAPIBundle::class => ['all' => true],
];
```

Create configuration files:

```
# config/routes/ov_json_rpc_api.yaml
ov_json_rpc_api:
    resource: '@OVJsonRPCAPIBundle/config/routes/routes.yaml'
```

```
# config/packages/ov_json_rpc_api.yaml
ov_json_rpc_api:
    access_control_allow_origin_list:
        - '*'
    swagger:
        api_v1:
            api_version: '1'
            base_path: '%env(string:OV_JSON_RPC_API_BASE_URL)%'
            base_path_description: 'Production server'
            test_path: '%env(string:OV_JSON_RPC_API_TEST_URL)%'
            test_path_description: 'Sandbox server'
            auth_token_name: 'X-AUTH-TOKEN'
            auth_token_test_value: '%env(string:OV_JSON_RPC_API_AUTH_TOKEN)%'
            info:
                title: 'My API'
                description: 'JSON-RPC 2.0 API'
                terms_of_service_url: 'https://example.com/tos'
                contact:
                    name: 'Support'
                    url: 'https://example.com'
                    email: 'support@example.com'
                license: 'MIT'
                licenseUrl: 'https://opensource.org/licenses/MIT'
```

```
# .env
OV_JSON_RPC_API_SWAGGER_PATH=public/openapi/
OV_JSON_RPC_API_BASE_URL=http://localhost
OV_JSON_RPC_API_TEST_URL=http://localhost
OV_JSON_RPC_API_AUTH_TOKEN=your_test_token_here
```

Detailed instructions: [docs/installation.md](./docs/installation.md)

---

Quick Start
-----------

[](#quick-start)

### 1. Create a Request

[](#1-create-a-request)

```
// src/RPC/V1/GetProduct/Request.php
namespace App\RPC\V1\GetProduct;

class Request
{
    private int $id;
    private string $title;

    public function __construct(int $id)
    {
        $this->id = $id;
    }

    public function getId(): int { return $this->id; }
    public function setId(int $id): void { $this->id = $id; }
    public function getTitle(): string { return $this->title; }
    public function setTitle(string $title): void { $this->title = $title; }
}
```

### 2. Create a Response

[](#2-create-a-response)

```
// src/RPC/V1/GetProduct/Response.php
namespace App\RPC\V1\GetProduct;

class Response
{
    private bool $success;
    private string $title;
    private int $price;

    public function __construct(bool $success = true)
    {
        $this->success = $success;
    }

    public function isSuccess(): bool { return $this->success; }
    public function setSuccess(bool $success): void { $this->success = $success; }
    public function getTitle(): string { return $this->title; }
    public function setTitle(string $title): void { $this->title = $title; }
    public function getPrice(): int { return $this->price; }
    public function setPrice(int $price): void { $this->price = $price; }
}
```

### 3. Create an API Method

[](#3-create-an-api-method)

```
// src/RPC/V1/GetProductMethod.php
namespace App\RPC\V1;

use OV\JsonRPCAPIBundle\Core\Annotation\JsonRPCAPI;
use OV\JsonRPCAPIBundle\Core\ApiMethodInterface;
use App\RPC\V1\GetProduct\Request;
use App\RPC\V1\GetProduct\Response;

#[JsonRPCAPI(methodName: 'getProduct', type: 'POST')]
class GetProductMethod implements ApiMethodInterface
{
    public function call(Request $request): Response
    {
        $response = new Response();
        $response->setTitle('Iphone 15');
        $response->setPrice(2000);
        return $response;
    }
}
```

### 4. Call the API

[](#4-call-the-api)

```
curl -X POST http://localhost/api/v1 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "method": "getProduct", "params": {"id": 1, "title": "test"}, "id": "1"}'
```

Response:

```
{
    "jsonrpc": "2.0",
    "result": {
        "success": true,
        "title": "Iphone 15",
        "price": 2000
    },
    "id": "1"
}
```

---

Architecture
------------

[](#architecture)

### Request Processing Pipeline

[](#request-processing-pipeline)

```
HTTP POST /api/v{version}
    |
    v
ApiController
    |
    v
RequestRawDataHandler --- parses HTTP request (JSON body / query params)
    |
    v
BatchStrategyFactory --- determines: single or batch request
    |
    v
RequestHandler
    |--- Lookup MethodSpec by method name
    |--- Create Request object from parameters
    |--- Validate typed properties
    |--- PreProcessors (if any)
    |--- Method::call(Request) -> Response
    |--- PostProcessors (if any)
    |
    v
ResponseService --- serializes response into JSON-RPC 2.0 format

```

### API Method Project Structure

[](#api-method-project-structure)

```
src/RPC/V1/
    GetProductMethod.php          # Method class with #[JsonRPCAPI] attribute
    GetProduct/
        Request.php               # Incoming request DTO
        Response.php              # Response DTO

```

Classes marked with the `#[JsonRPCAPI]` attribute are automatically discovered and registered by the bundle.

---

Examples
--------

[](#examples)

ExampleDescriptionFiles[Basic](./docs/examples/base.md)Simplest example of creating an API methodRequest, Response, Method[Pre/Post-processors](./docs/examples/pre-and-post-processors.md)Executing logic before and after method callRequest, Response, Method, AbstractMethod[Array of objects](./docs/examples/array_of_objects.md)Returning a collection of objects in the responseRequest, Response, Method, Product[Binary response](./docs/examples/plain_response.md)Returning images, documents and other binary dataRequest, PlainResponse, Method---

Additional Documentation
------------------------

[](#additional-documentation)

SectionDescription[Error Handling](./docs/errors.md)Error codes, `JRPCException`, custom errors, `additionalInfo`[Notification Requests](./docs/notifications.md)Requests without `id`, `strict_notifications` parameter[Parameter Validation](./docs/validation.md)Automatic type validation, nullable, error format[JsonRpcRequest Base Class](./docs/json_rpc_request.md)`toArray()` method, recursive serialization[Partial updates (JSON Merge Patch)](./docs/partial_updates.md)`PartialRequestInterface`, `wasProvided()`, RFC 7396 semantics[Troubleshooting / FAQ](./docs/troubleshooting.md)Common problems and their solutions[**Upgrade Guide 4.x → 5.0**](./docs/upgrade-5.0.en.md)**Every BC-breaking change in 5.0, what breaks and what to do about it**[CHANGELOG](./CHANGELOG.md)Version history---

Logging
-------

[](#logging)

Optional Request/Response logging subsystem with sensitive-data masking through a PSR-3 logger. Disabled by default. Details — [docs/logging.md](docs/logging.md).

---

Partial updates (JSON Merge Patch)
----------------------------------

[](#partial-updates-json-merge-patch)

The bundle supports PATCH semantics per [RFC 7396](https://datatracker.ietf.org/doc/html/rfc7396) for Update methods where the client sends only changed fields.

**Problem:** the standard `if ($request->getX() !== null) { $entity->setX($request->getX()); }` pattern cannot distinguish "field not in payload" from "field sent as `null`" — both give `null` on the DTO. This means a field cannot be **cleared** via PATCH.

**Solution:** the Request DTO implements `PartialRequestInterface`, and the framework tracks which fields actually arrived in the payload. The service layer uses `wasProvided('x')` instead of `!== null`:

```
use OV\JsonRPCAPIBundle\Core\Request\PartialUpdateRequest;

class UpdateUserRequest extends PartialUpdateRequest
{
    private ?int $id = null;
    private ?string $email = null;
    private ?string $bio = null;
    // getters/setters...
}
```

```
public function call(UpdateUserRequest $request): Response
{
    $user = $this->userRepository->find($request->getId());

    if ($request->wasProvided('email')) {
        $user->setEmail($request->getEmail()); // null = clear
    }
    if ($request->wasProvided('bio')) {
        $user->setBio($request->getBio());
    }
    // ...
}
```

**Payload semantics:**

Payload`wasProvided`Service behavior`{"email": "new@x.com"}``true`set the new value`{"email": null}``true`clear the field (`null`)`{}` (key absent)`false`leave the field untouched**Opt-in:** only DTOs implementing `PartialRequestInterface` get tracking. Existing DTOs work without changes (full backward compatibility).

Details and edge cases — in [docs/partial\_updates.md](./docs/partial_updates.md).

---

API Versioning
--------------

[](#api-versioning)

API version is determined from the URL (`/api/v1`, `/api/v2`) or explicitly via the `version` parameter in the attribute:

```
#[JsonRPCAPI(methodName: 'getProduct', type: 'POST', version: 2)]
```

If `version` is not specified, it's extracted from the class namespace (e.g., `App\RPC\V1` -&gt; version 1).

---

Batch Requests
--------------

[](#batch-requests)

The bundle supports batch JSON-RPC requests per specification:

```
curl -X POST http://localhost/api/v1 \
  -H "Content-Type: application/json" \
  -d '[
    {"jsonrpc": "2.0", "method": "sum", "params": [1, 2, 4], "id": "1"},
    {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
    {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": "2"}
  ]'
```

---

Pre- and Post-processors
------------------------

[](#pre--and-post-processors)

Processors allow executing logic before and after API method calls (logging, audit, notifications, etc.):

```
use OV\JsonRPCAPIBundle\Core\PreProcessorInterface;
use OV\JsonRPCAPIBundle\Core\PostProcessorInterface;

#[JsonRPCAPI(methodName: 'getProduct', type: 'POST')]
class GetProductMethod implements PreProcessorInterface, PostProcessorInterface
{
    public function getPreProcessors(): array
    {
        return [
            static::class => ['logRequest'],
        ];
    }

    public function getPostProcessors(): array
    {
        return [
            static::class => ['logResponse'],
        ];
    }

    public function logRequest(string $processorClass, ?object $request = null): void
    {
        // Called BEFORE call()
    }

    public function logResponse(string $processorClass, ?object $request = null, ?OvResponseInterface $response = null): void
    {
        // Called AFTER call()
    }

    public function call(Request $request): Response
    {
        // Main logic
    }
}
```

Details: [docs/examples/pre-and-post-processors.md](./docs/examples/pre-and-post-processors.md)

---

Swagger / OpenAPI
-----------------

[](#swagger--openapi)

### Generating Documentation

[](#generating-documentation)

```
bin/console ov:swagger:generate
```

Generates `public/openapi/api_v1.yaml` file for use with Swagger UI.

### Documentation Annotations

[](#documentation-annotations)

**Scalar properties:**

```
use OV\JsonRPCAPIBundle\Core\Annotation\SwaggerProperty;

class Response
{
    #[SwaggerProperty(default: 'true', example: 'true')]
    private bool $success;

    #[SwaggerProperty(format: 'email', example: 'user@example.com')]
    private string $email;
}
```

**Arrays:**

```
use OV\JsonRPCAPIBundle\Core\Annotation\SwaggerArrayProperty;

class Response
{
    #[SwaggerArrayProperty(type: 'string')]
    private array $errors = [];

    #[SwaggerArrayProperty(type: Product::class, ofClass: true)]
    private array $products = [];
}
```

**Tags for grouping:**

```
#[JsonRPCAPI(methodName: 'getProduct', type: 'POST', tags: ['products'])]
```

Details:

- [Tags](./docs/swagger/tags.md)
- [Scalar properties](./docs/swagger/scalar.md)
- [Arrays](./docs/swagger/array.md)

---

Security
--------

[](#security)

### Role-Based Access

[](#role-based-access)

Restrict method access by roles via the `roles` attribute:

```
#[JsonRPCAPI(
    methodName: 'deleteUser',
    type: 'POST',
    roles: ['ROLE_ADMIN', 'ROLE_SUPER_ADMIN']
)]
class DeleteUserMethod implements ApiMethodInterface
{
    public function call(Request $request): Response { /* ... */ }
}
```

If the user lacks the required role, the bundle returns a normal JSON-RPC error object with code `-32000` and HTTP status 200 — **not** HTTP 403: `{"jsonrpc": "2.0", "error": {"code": -32000, "message": "Access denied."}, "id": ...}`.

### Authentication

[](#authentication)

The bundle is compatible with any Symfony authentication method:

- [JWT tokens via lexik/jwt-authentication-bundle](./docs/security/jwt_bundle.md)
- [Custom token authentication](./docs/security/self_made_token.md)
- [Role model](./docs/security/roles.md)

---

Testing
-------

[](#testing)

Run the test suite:

```
./vendor/bin/phpunit tests/
```

Coverage reports require a coverage driver (xdebug or pcov). The `phpunit.xml.dist` config already declares the `` block for PHPUnit 10+ coverage output.

The bundled test suite covers:

- **Unit tests** — every Core component, services, request/response models, DI, Swagger models.
- **Integration tests** — full request lifecycle through the controller.
- **Command tests** — Swagger YAML generation.
- **Security regression tests** (`tests/Security/`) — DoS limits (payload, batch, DTO depth, array size), error sanitization, CORS origin matching, setter visibility, command path containment.

See [docs/testing.md](./docs/testing.md) for guidance on writing tests for your own RPC methods.

---

Configuration
-------------

[](#configuration)

### `ov_json_rpc_api` Parameters

[](#ov_json_rpc_api-parameters)

ParameterDefaultDescription`access_control_allow_origin_list``[]`Allowed CORS origins. Use `['*']` for wildcard, or list exact origins for matching against the request `Origin` header. Origins outside the list receive no CORS header at all — the legacy comma-joined fallback no longer exists.`cors_allowed_headers``['Content-Type']`Headers allowed in the CORS preflight response (`Access-Control-Allow-Headers`). The bundle handles `OPTIONS` preflight requests itself.`strict_notifications``true`Strict JSON-RPC 2.0 Notification compliance. When `true` — server does not respond to notifications (per spec). When `false` — server returns a response even for notifications if the result is non-empty (legacy 3.x behaviour).`allow_extra_fields``false`When `false`, request params containing fields not declared on the Request DTO are rejected with `INVALID_PARAMS`. Can be overridden per-method via the `#[JsonRPCAPI(allowExtraFields: true)]` attribute.`expose_internal_errors``false`When `false` (production-safe), uncaught non-`JRPCException` throwables are replaced with a generic `Internal error.` payload and the original is sent to the logger. Set to `true` only in dev to expose raw exception messages.`max_payload_bytes``1048576`Maximum bytes accepted for the raw request body. Larger requests are rejected with `INVALID_REQUEST`.`max_json_depth``64`Maximum allowed JSON nesting depth when decoding the payload. Deeper inputs are rejected with `PARSE_ERROR`.`max_batch_size``50`Maximum number of requests allowed in a single JSON-RPC batch. Larger batches return a single `INVALID_REQUEST` error.`max_dto_depth``10`Maximum recursion depth when hydrating nested Request DTO objects. Prevents stack/memory exhaustion via deeply nested payloads.`max_array_param_size``1000`Maximum element count for array parameters bound through `addX()` adders.`logging.enabled``false`Request and response logging. Everything else under `logging.*` applies only when this is `true`.`logging.request_level``'info'`PSR-3 level for the incoming request entry.`logging.response_level``'info'`PSR-3 level for a successful response entry.`logging.error_response_level``'warning'`PSR-3 level for an error response entry.`logging.max_body_length``8192`Truncation of request and response bodies in the log, in characters. `0` disables truncation. **The 4.x default was `0`.**`logging.skip_plain_responses``true`Do not log the body of `PlainResponseInterface` responses (files, streams).`logging.logger_service``null`Service id of the PSR-3 logger `JsonRpcCallLogger` writes to.`logging.call_logger_service``null`Service id replacing the `JsonRpcCallLoggerInterface` implementation outright.`logging.masking.placeholder``'***'`What replaces the value of a masked field.`logging.masking.key_patterns`29 patternsRegular expressions for field and header names whose values are masked (`password`, `token`, `secret`, `authorization`, `jwt` and others). **The 4.x default was `[]`, meaning no masking at all.** Supplying your own list replaces the defaults rather than adding to them. An invalid expression fails container compilation.`swagger`—Swagger configuration per API version.`swagger.*.api_version``'1'`API version number.`swagger.*.base_path`—Production server URL.`swagger.*.test_path``null`Test server URL.`swagger.*.base_path_variables``[]`Variables for base\_path substitution.`swagger.*.test_path_variables``[]`Variables for test\_path substitution.`swagger.*.auth_token_name`—Authorization token header name.`swagger.*.auth_token_test_value`—Test token value. **Currently unused:** only `auth_token_name` reaches the OpenAPI security scheme; the value is substituted nowhere. Kept so existing configs keep compiling.`swagger.*.info`—API information (title, description, contact, license).> **Security hardening:** see [docs/security\_hardening.md](./docs/security_hardening.md) for recommended values, rationale, and tuning tips for high-volume APIs.

---

`#[JsonRPCAPI]` Attribute Parameters
------------------------------------

[](#jsonrpcapi-attribute-parameters)

ParameterTypeRequiredDefaultDescription`methodName`stringyes—JSON-RPC method name`type`stringyes—HTTP method (POST, GET, PUT, PATCH, DELETE)`version`?intno`null`API version (if null — determined from namespace)`summary`stringno`''`Short description for Swagger`description`stringno`''`Detailed description for Swagger`tags`?arrayno`null`Tags for Swagger grouping`roles`arrayno`[]`Required roles for access`ignoreInSwagger`boolno`false`Exclude method from Swagger documentation`group`?stringno`null`Swagger path group (e.g., `'products'` -&gt; `/products/get_product`)`allowExtraFields`boolno`false`Accept fields in `params` that the Request DTO does not declare. Overrides the global `allow_extra_fields` for this method and applies at every nesting level.---

JSON-RPC Error Codes
--------------------

[](#json-rpc-error-codes)

CodeConstantDescription`-32700``PARSE_ERROR`JSON parsing error`-32600``INVALID_REQUEST`Invalid JSON-RPC request`-32601``METHOD_NOT_FOUND`Method not found`-32602``INVALID_PARAMS`Invalid parameters`-32603``INTERNAL_ERROR`Internal error`-32000``SERVER_ERROR`Server error---

Contributing
------------

[](#contributing)

See [CONTRIBUTING.md](./CONTRIBUTING.md) for the development setup, test requirements, and PR expectations. To report a vulnerability, see [SECURITY.md](./SECURITY.md) — please do not open a public issue.

License
-------

[](#license)

[MIT](https://opensource.org/licenses/MIT)

Author
------

[](#author)

Leonid Groshev —  — [otezvikentiy.tech](https://otezvikentiy.tech)

###  Health Score

55

—

FairBetter than 97% of packages

Maintenance99

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity76

Established project with proven stability

 Bus Factor1

Top contributor holds 99.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~19 days

Total

58

Last Release

4d ago

Major Versions

1.36 → 2.02025-09-01

2.18 → 3.22026-03-30

3.9 → 4.02026-05-11

4.2 → 5.0-stable2026-08-07

PHP version history (3 changes)1.0.15PHP &gt;=8.1

2.0PHP &gt;=8.2

5.0-stablePHP 8.2.\* || 8.3.\* || 8.4.\* || 8.5.\*

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/19647948?v=4)[OtezVikentiy](/maintainers/OtezVikentiy)[@OtezVikentiy](https://github.com/OtezVikentiy)

---

Top Contributors

[![OtezVikentiy](https://avatars.githubusercontent.com/u/19647948?v=4)](https://github.com/OtezVikentiy "OtezVikentiy (175 commits)")[![andreybolonin](https://avatars.githubusercontent.com/u/2576509?v=4)](https://github.com/andreybolonin "andreybolonin (1 commits)")

---

Tags

apibundlejsonjson-rpc-2jsonrpcjsonrpc-serveropenapiphpphp8rpcswaggersymfonysymfony-bundleapisymfonybundleswaggerjsonrpc

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/otezvikentiy-json-rpc-api/health.svg)

```
[![Health](https://phpackages.com/badges/otezvikentiy-json-rpc-api/health.svg)](https://phpackages.com/packages/otezvikentiy-json-rpc-api)
```

###  Alternatives

[chameleon-system/chameleon-base

The Chameleon System core.

1029.4k6](/packages/chameleon-system-chameleon-base)[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.5k6.0M775](/packages/sylius-sylius)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.8M666](/packages/shopware-core)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M231](/packages/sulu-sulu)[easycorp/easyadmin-bundle

Admin generator for Symfony applications

4.3k18.3M417](/packages/easycorp-easyadmin-bundle)[pimcore/pimcore

Content &amp; Product Management Framework (CMS/PIM/E-Commerce)

3.8k3.9M534](/packages/pimcore-pimcore)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
