PHPackages                             php-skir/server - 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. php-skir/server

ActiveLibrary[API Development](/categories/api)

php-skir/server
===============

Laravel SkirRPC server package.

v0.1.4(1mo ago)019MITPHP ^8.4

Since Jul 6Compare

[ Source](https://github.com/php-skir/server)[ Packagist](https://packagist.org/packages/php-skir/server)[ Docs](https://github.com/php-skir/server)[ RSS](/packages/php-skir-server/feed)WikiDiscussions Synced 1w ago

READMEChangelogDependencies (18)Versions (7)Used By (0)

Laravel Skir Server
===================

[](#laravel-skir-server)

Laravel package for exposing SkirRPC methods from a Laravel application.

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

[](#installation)

```
composer require php-skir/server
```

Generated server procedures
---------------------------

[](#generated-server-procedures)

Start with a Skir method definition:

```
// skir-src/admin/users.skir
struct GetUserRequest {
  user_id: int32;
}

struct User {
  user_id: int32;
  name: string;
}

method GetUser(GetUserRequest): User = 3180856469;

```

Configure one of the PHP generators in `skir.yml`:

```
generators:
  - mod: skir-laravel-data-generator
    outDir: app/SkirGenerated
    config:
      namespace: App\Skir
```

Then run generation from your Laravel app:

```
php artisan skir:generate-client
```

For every module that contains methods, the generator writes:

```
app/SkirGenerated/Admin/SkirMethods.php
app/SkirGenerated/Admin/AdminSkirMethod.php
app/SkirGenerated/Admin/AbstractSkirProcedures.php
app/SkirGenerated/Admin/SkirProcedures.php
app/SkirGenerated/Admin/SkirProcedureProvider.php

```

Make sure the output directory is covered by Composer autoloading. For example, map `App\\Skir\\` to `app/SkirGenerated/` or choose an output directory that already matches your app's autoload setup.

Register a Skir endpoint as one service and compose it from controllers:

```
use App\Skir\Controllers\UserController;
use Illuminate\Support\Facades\Route;
use Skir\Server\Facades\Skir;

Route::skirRpc('/api/skir', [
    Skir::controller(UserController::class),
])->studio();
```

Controller methods are registered only when they have a `SkirMethod` attribute. The PHP method name is not used for Skir method resolution; the generated enum case is the source of truth.

```
namespace App\Skir\Controllers;

use App\Models\User as UserModel;
use App\Skir\Admin\AdminSkirMethod;
use App\Skir\Admin\GetUserRequestData;
use App\Skir\Admin\UserData;
use Skir\Server\Attributes\SkirMethod;
use Skir\Server\SkirContext;

final class UserController
{
    #[SkirMethod(AdminSkirMethod::GetUser)]
    public function get(GetUserRequestData $request, SkirContext $context): UserData
    {
        $user = UserModel::query()->findOrFail($request->userId);

        return new UserData(
            userId: $user->id,
            name: $user->name,
        );
    }
}
```

The controller dispatcher handles the repetitive work:

- Registers every generated `SkirMethods::*()` descriptor with the endpoint.
- Hydrates incoming payloads into generated request DTOs.
- Calls your attributed controller methods.
- Converts returned DTOs back into Skir payload arrays.

With `skir-laravel-data-generator`, request hydration uses `makeFromSkirPayload()`, so Laravel Data validation runs before your procedure method is called.

For one-method controllers, register an invokable controller explicitly:

```
use App\Skir\Admin\AdminSkirMethod;
use App\Skir\Controllers\GetUserController;
use Illuminate\Support\Facades\Route;
use Skir\Server\Facades\Skir;

Route::skirRpc('/api/skir', [
    Skir::method(AdminSkirMethod::GetUser, GetUserController::class),
]);
```

Standard PHP DTO example
------------------------

[](#standard-php-dto-example)

When using `skir-php-generator`, controller methods use standard PHP DTOs:

```
namespace App\Skir\Controllers;

use App\Skir\Admin\AdminSkirMethod;
use App\Skir\Admin\GetUserRequest;
use App\Skir\Admin\User;
use Skir\Server\Attributes\SkirMethod;
use Skir\Server\SkirContext;

final class UserController
{
    #[SkirMethod(AdminSkirMethod::GetUser)]
    public function get(GetUserRequest $request, SkirContext $context): User
    {
        return new User(
            userId: $request->userId,
            name: 'Maxim',
        );
    }
}
```

Compatibility APIs
------------------

[](#compatibility-apis)

The lower-level provider APIs remain available for manual adapters and backwards compatibility:

```
use App\Skir\Admin\AdminProcedures;
use App\Skir\Admin\SkirProcedureProvider;
use App\Skir\Admin\SkirProcedures;
use Illuminate\Support\Facades\Route;

$this->app->bind(SkirProcedures::class, AdminProcedures::class);

Route::skirRpc('/api/skir', [
    SkirProcedureProvider::class,
]);
```

`RequestContext` is still accepted as a compatibility type. New code should type-hint `SkirContext`.

Manual registration
-------------------

[](#manual-registration)

You can still register handlers manually. This is useful for tests, tiny endpoints, or experiments.

Register an endpoint in your routes file:

```
use Illuminate\Support\Facades\Route;

Route::skirRpc('/api/skir');
```

Register generated Skir method descriptors with handlers:

```
use Skir\Runtime\MethodDescriptor;
use Skir\Runtime\Type;
use Skir\Server\SkirContext;
use Skir\Server\SkirServer;

app(SkirServer::class)->addMethod(
    new MethodDescriptor('Square', 1001, Type::float32(), Type::float32()),
    fn (float $value, SkirContext $context): float => $value * $value,
);
```

The endpoint accepts SkirRPC request envelopes:

```
{"method":"Square","request":5.0}
```

Responses are returned as raw Skir dense JSON values:

```
25
```

GET requests are also supported by passing `method` and a JSON-encoded `request` query parameter.

Studio
------

[](#studio)

Studio is disabled by default. Enable it per endpoint:

```
Route::skirRpc('/api/skir', [
    Skir::controller(UserController::class),
])->studio();
```

Then open `/api/skir?studio` in a browser. Studio renders the methods registered on that endpoint only, so separate Skir endpoints keep separate procedure lists.

Codecs
------

[](#codecs)

Dense JSON is the default endpoint codec:

```
Route::skirRpc('/api/skir', [
    Skir::controller(UserController::class),
]);
```

You can choose a codec per endpoint:

```
use Skir\Server\Codecs\SkirCodecs;

Route::skirRpc('/api/skir-readable', [
    Skir::controller(UserController::class),
], SkirCodecs::standardJson());

Route::skirRpc('/api/skir-base64', [
    Skir::controller(UserController::class),
], SkirCodecs::base64DenseJson());

Route::skirRpc('/api/skir-cbor', [
    Skir::controller(UserController::class),
], SkirCodecs::cbor());
```

- `denseJson()` decodes and encodes Skir dense JSON values. This is the default for production APIs.
- `standardJson()` passes decoded JSON values through unchanged. Use it when you want readable JSON at the HTTP boundary and your procedures/generated providers handle that shape.
- `base64DenseJson()` accepts and returns base64-encoded dense JSON strings inside the JSON envelope.
- `cbor()` accepts an `application/cbor` request body with `method` and dense `request` values, and returns an `application/cbor` response body.

CBOR support is optional. Install `spomky-labs/cbor-php` in the consuming app before using `SkirCodecs::cbor()`.

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance93

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

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 ~3 days

Total

5

Last Release

34d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/91a724ec7e90c57050c6fa0fa34f9faeec7041896866d4f8ddc85ed00b0f8887?d=identicon)[happyDemon](/maintainers/happyDemon)

---

Tags

phplaravelrpcserializationskir

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/php-skir-server/health.svg)

```
[![Health](https://phpackages.com/badges/php-skir-server/health.svg)](https://phpackages.com/packages/php-skir-server)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.4M354](/packages/psalm-plugin-laravel)[api-platform/laravel

API Platform support for Laravel

58190.1k21](/packages/api-platform-laravel)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

79227.1M246](/packages/laravel-mcp)[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.6k31.8M163](/packages/laravel-cashier)[defstudio/telegraph

A laravel facade to interact with Telegram Bots

818355.4k3](/packages/defstudio-telegraph)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45844.8k1](/packages/pressbooks-pressbooks)

PHPackages © 2026

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