Laravel package for exposing SkirRPC methods from a Laravel application.
Skir is a modern schema language for defining data models and APIs. You describe your structs, enums, and RPC methods once in .skir files, then generate clean, idiomatic, and type-safe code across your stack. Skir includes generators for TypeScript, Python, Java, Go, C#, C++, Kotlin, Rust, Swift, and more, while the PHP generators in this ecosystem bring the same schema-first workflow to Laravel. This gives your backend, frontend, and other services a shared source of truth instead of separately maintained DTOs and API contracts.
SkirRPC offers many of the same benefits as gRPC—shared method definitions, generated clients and servers, and end-to-end type safety—but runs over standard HTTP requests and integrates with the frameworks you already use. This package brings that workflow to Laravel: generated contracts handle serialization and type information, while your procedures remain ordinary Laravel controllers resolved through the container.
- Generate typed server contracts with Simple Data Objects, Laravel Data, or standard PHP objects. See Generated procedures.
- Scaffold application-owned controllers and Form Requests from generated manifests. See Scaffolding.
- Route procedures to attributed or invokable Laravel controllers with native dependency injection, middleware, authorization, and Form Requests. See Routing.
- Keep generated providers and manual handlers available for non-controller layouts. See Routing.
- Inspect an endpoint's procedures through its opt-in Studio. See Studio.
- Configure dense JSON, standard JSON, base64 dense JSON, or CBOR package-wide or per endpoint. See Codecs.
Install the server package and one PHP generator. This example uses Simple Data Objects:
composer require php-skir/server std-out/simple-data-objects
npm install --save-dev skir skir-simple-data-objects-generatorThe package defaults match the paths used below. To customize manifest locations, generator execution, controller layout, Form Request generation, Studio, or codecs, publish config/skir-server.php:
php artisan vendor:publish --tag=skir-server-configSee Scaffolding configuration for the current keys and defaults. Calling studio() or studio(false) on a route overrides the Studio default, while an explicit codec passed to Route::skirRpc() overrides the configured codec.
Define a Skir method:
// skir-src/admin/users.skir
struct GetUserRequest {
user_id: int32;
}
struct User {
user_id: int32;
name: string;
}
method GetUser(GetUserRequest): User = 3180856469;
Configure the generator in skir.yml:
generators:
- mod: skir-simple-data-objects-generator
outDir: app/Skir/skirout
config:
namespace: SkirSkir requires every output directory to end in /skirout. It owns that directory and may replace or remove files inside it, so keep handwritten application code elsewhere.
Generate the PHP contracts, configure Composer, and refresh the autoloader:
npx skir gen
npx skir-simple-data-objects-generator configure-composer
composer dump-autoloadThe configure-composer command reads skir.yml and adds this PSR-4 mapping to composer.json when it is missing:
{
"autoload": {
"psr-4": {
"Skir\\": "app/Skir/skirout/"
}
}
}Keep controllers outside skirout; the default application-owned namespace is App\Skir. Scaffold every generated method and its Form Request with:
php artisan skir:make --allGenerated Form Requests deny access by default; define their authorize() and rules() methods before exposing the procedure. The command prints the route registrations to add. A module controller has this shape:
<?php
declare(strict_types=1);
namespace App\Skir\Admin;
use App\Http\Requests\Skir\Admin\GetUserFormRequest;
use App\Models\User as UserModel;
use Skir\Admin\AdminSkirMethod;
use Skir\Admin\UserData;
use Skir\Server\Attributes\SkirMethod;
final class AdminController
{
#[SkirMethod(AdminSkirMethod::GetUser)]
public function getUser(GetUserFormRequest $request): UserData
{
$input = $request->skir();
$user = UserModel::query()->findOrFail($input->userId);
return new UserData(
userId: $user->id,
name: $user->name,
);
}
}Register the controller on a SkirRPC endpoint:
use App\Skir\Admin\AdminController;
use Illuminate\Support\Facades\Route;
use Skir\Server\Facades\Skir;
Route::skirRpc('/api/skir', [
Skir::controller(AdminController::class),
])->studio();Only public controller methods carrying a SkirMethod attribute are registered. The generated enum case identifies the Skir method; the PHP method name does not.
The studio() call explicitly enables the endpoint-scoped Studio regardless of the configured default. With the default query key, Studio is available at /api/skir?studio. See Routing and Studio for middleware, authorization, and alternative routing layouts.
The php-skir/client package is not required to host a SkirRPC server. It normally belongs in the application consuming this endpoint.
