Everything you need to start building type-safe APIs with StoneScriptPHP
composer require progalaxyelabs/stonescriptphp
Create a PHP interface that defines your API endpoints
<?php
namespace App\Contracts;
interface UserContract {
public function getUser(int $id): UserDTO;
public function createUser(CreateUserDTO $dto): UserDTO;
public function updateUser(int $id, UpdateUserDTO $dto): UserDTO;
public function deleteUser(int $id): void;
}
Define data transfer objects with proper typing
<?php
namespace App\DTOs;
class UserDTO {
public int $id;
public string $name;
public string $email;
public ?string $avatar;
public \DateTime $createdAt;
}
class CreateUserDTO {
public string $name;
public string $email;
public string $password;
}
Create a service class that implements your contract
<?php
namespace App\Services;
use App\Contracts\UserContract;
use App\DTOs\UserDTO;
use App\DTOs\CreateUserDTO;
class UserService implements UserContract {
public function getUser(int $id): UserDTO {
// Your implementation here
$user = new UserDTO();
$user->id = $id;
$user->name = "John Doe";
$user->email = "john@example.com";
return $user;
}
public function createUser(CreateUserDTO $dto): UserDTO {
// Your implementation here
}
}
Run the code generator to create your TypeScript client
php artisan stonescript:generate-client
This generates a type-safe TypeScript client:
// Auto-generated TypeScript client
export class UserClient {
constructor(private http: HttpClient) {}
getUser(id: number): Observable<UserDTO> {
return this.http.post<UserDTO>('/api/user/getUser', { id });
}
createUser(dto: CreateUserDTO): Observable<UserDTO> {
return this.http.post<UserDTO>('/api/user/createUser', dto);
}
}
export interface UserDTO {
id: number;
name: string;
email: string;
avatar: string | null;
createdAt: string;
}
Import and use the generated client in your Angular app
import { Component } from '@angular/core';
import { UserClient, UserDTO } from './api/user-client';
@Component({
selector: 'app-user-list',
template: `
<div *ngFor="let user of users">
{{ user.name }} - {{ user.email }}
</div>
`
})
export class UserListComponent {
users: UserDTO[] = [];
constructor(private userClient: UserClient) {
this.loadUsers();
}
loadUsers() {
this.userClient.getUser(1).subscribe(user => {
this.users.push(user);
});
}
}
Configure StoneScriptPHP in your project
<?php
return [
'contracts_path' => 'app/Contracts',
'dtos_path' => 'app/DTOs',
'output_path' => 'resources/ts/api',
'namespace' => 'App',
'route_prefix' => '/api',
'middleware' => ['api', 'auth:sanctum'],
];
Join our community and explore the ecosystem