PHP code example of webfiori / rest-easy

1. Go to this page and download the library: Download webfiori/rest-easy library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

webfiori / rest-easy example snippets





use WebFiori\Http\WebService;
use WebFiori\Http\Annotations\RestController;
use WebFiori\Http\Annotations\GetMapping;
use WebFiori\Http\Annotations\PostMapping;
use WebFiori\Http\Annotations\RequestParam;
use WebFiori\Http\Annotations\ResponseBody;
use WebFiori\Http\Annotations\AllowAnonymous;
use WebFiori\Http\ParamType;

#[RestController('hello', 'A simple greeting service')]
class HelloService extends WebService {
    
    #[GetMapping]
    #[ResponseBody]
    #[AllowAnonymous]
    #[RequestParam('name', ParamType::STRING, true)]
    public function sayHello(?string $name): string {
        return $name ? "Hello, $name!" : "Hello, World!";
    }
    
    #[PostMapping]
    #[ResponseBody]
    #[AllowAnonymous]
    #[RequestParam('message', ParamType::STRING)]
    public function customGreeting(string $message): array {
        return ['greeting' => $message, 'timestamp' => time()];
    }
}


use WebFiori\Http\AbstractWebService;
use WebFiori\Http\RequestMethod;
use WebFiori\Http\ParamType;
use WebFiori\Http\ParamOption;

class HelloService extends AbstractWebService {
    public function __construct() {
        parent::__construct('hello');
        $this->setRequestMethods([RequestMethod::GET]);
        
        $this->addParameters([
            'name' => [
                ParamOption::TYPE => ParamType::STRING,
                ParamOption::OPTIONAL => true
            ]
        ]);
    }
    
    public function isAuthorized() {
        return true;
    }
    
    public function processRequest() {
        $name = $this->getParamVal('name');
        $this->sendResponse($name ? "Hello, $name!" : "Hello, World!");
    }
}

// Recommended: process a single service directly
$processor = new RequestProcessor();
$processor->process(new HelloService());

// Legacy: register services in a manager
$manager = new WebServicesManager();
$manager->addService(new HelloService());
$manager->process();


use WebFiori\Http\WebService;
use WebFiori\Http\Annotations\RestController;
use WebFiori\Http\Annotations\GetMapping;
use WebFiori\Http\Annotations\PostMapping;
use WebFiori\Http\Annotations\PutMapping;
use WebFiori\Http\Annotations\DeleteMapping;
use WebFiori\Http\Annotations\RequestParam;
use WebFiori\Http\Annotations\ResponseBody;
use WebFiori\Http\Annotations\RequiresAuth;
use WebFiori\Http\ParamType;

#[RestController('users', 'User management operations')]
#[RequiresAuth]
class UserService extends WebService {
    
    #[GetMapping]
    #[ResponseBody]
    #[RequestParam('id', ParamType::INT, true)]
    public function getUser(?int $id): array {
        return ['id' => $id ?? 1, 'name' => 'John Doe'];
    }
    
    #[PostMapping]
    #[ResponseBody]
    #[RequestParam('name', ParamType::STRING)]
    #[RequestParam('email', ParamType::EMAIL)]
    public function createUser(string $name, string $email): array {
        return ['id' => 2, 'name' => $name, 'email' => $email];
    }
    
    #[PutMapping]
    #[ResponseBody]
    #[RequestParam('id', ParamType::INT)]
    #[RequestParam('name', ParamType::STRING)]
    public function updateUser(int $id, string $name): array {
        return ['id' => $id, 'name' => $name];
    }
    
    #[DeleteMapping]
    #[ResponseBody]
    #[RequestParam('id', ParamType::INT)]
    public function deleteUser(int $id): array {
        return ['deleted' => $id];
    }
}


use WebFiori\Http\AbstractWebService;
use WebFiori\Http\RequestMethod;

class MyService extends AbstractWebService {
    public function __construct() {
        parent::__construct('my-service');
        $this->setRequestMethods([RequestMethod::GET, RequestMethod::POST]);
        $this->setDescription('A sample web service');
    }
    
    public function isAuthorized() {
        // Implement authorization logic
        return true;
    }
    
    public function processRequest() {
        // Implement service logic
        $this->sendResponse('Service executed successfully');
    }
}

// Single method
$this->addRequestMethod(RequestMethod::POST);

// Multiple methods
$this->setRequestMethods([
    RequestMethod::GET,
    RequestMethod::POST,
    RequestMethod::PUT
]);

$this->setDescription('Creates a new user profile');
$this->setSince('1.2.0');
$this->addResponseDescription('Returns user profile data on success');
$this->addResponseDescription('Returns error message on failure');

ParamType::STRING    // String values
ParamType::INT       // Integer values
ParamType::DOUBLE    // Float/double values
ParamType::BOOL      // Boolean values
ParamType::EMAIL     // Email addresses (validated)
ParamType::URL       // URLs (validated)
ParamType::ARR       // Arrays
ParamType::JSON_OBJ  // JSON objects

use WebFiori\Http\RequestParameter;

$param = new RequestParameter('username', ParamType::STRING);
$this->addParameter($param);

$this->addParameters([
    'username' => [
        ParamOption::TYPE => ParamType::STRING,
        ParamOption::OPTIONAL => false
    ],
    'age' => [
        ParamOption::TYPE => ParamType::INT,
        ParamOption::OPTIONAL => true,
        ParamOption::MIN => 18,
        ParamOption::MAX => 120,
        ParamOption::DEFAULT => 25
    ],
    'email' => [
        ParamOption::TYPE => ParamType::EMAIL,
        ParamOption::OPTIONAL => false
    ]
]);

ParamOption::TYPE         // Parameter data type
ParamOption::OPTIONAL     // Whether parameter is optional
ParamOption::DEFAULT      // Default value for optional parameters
ParamOption::MIN          // Minimum value (numeric types)
ParamOption::MAX          // Maximum value (numeric types)
ParamOption::MIN_LENGTH   // Minimum length (string types)
ParamOption::MAX_LENGTH   // Maximum length (string types)
ParamOption::EMPTY        // Allow empty strings
ParamOption::FILTER       // Custom filter function
ParamOption::DESCRIPTION  // Parameter description
ParamOption::ALLOWED_VALUES // Restrict to a set of allowed values
ParamOption::PATTERN      // Regex pattern for validation

$this->addParameters([
    'password' => [
        ParamOption::TYPE => ParamType::STRING,
        ParamOption::MIN_LENGTH => 8,
        ParamOption::FILTER => function($original, $basic) {
            // Custom validation logic
            if (strlen($basic) < 8) {
                return APIFilter::INVALID;
            }
            // Additional password strength checks
            return $basic;
        }
    ]
]);

public function processRequest() {
    $username = $this->getParamVal('username');
    $age = $this->getParamVal('age');
    $email = $this->getParamVal('email');
    
    // Get all inputs as array
    $allInputs = $this->getInputs();
}

#[GetMapping]
#[ResponseBody]
#[AllowAnonymous]
#[RequestParam('app-id', ParamType::INT)]
#[RequestParam('user-name', ParamType::STRING, true)]
public function getData(int $id, ?string $name): array {
    // $id receives the value of 'app-id' (1st attribute → 1st parameter)
    // $name receives the value of 'user-name' (2nd attribute → 2nd parameter)
    return ['id' => $id, 'name' => $name];
}

#[PostMapping]
#[ResponseBody]
#[RequestParam(name: 'notes', type: ParamType::STRING, optional: true, allowEmpty: true)]
public function create(?string $notes): array {
    return ['notes' => $notes ?? ''];
}

class PaginationParams implements ParameterSet {
    public function getParameters(): array {
        return [
            'page' => [ParamOption::TYPE => ParamType::INT, ParamOption::OPTIONAL => true, ParamOption::DEFAULT => 1],
            'per_page' => [ParamOption::TYPE => ParamType::INT, ParamOption::OPTIONAL => true, ParamOption::DEFAULT => 20],
        ];
    }
}

#[GetMapping]
#[ResponseBody]
#[UseParameterSet(PaginationParams::class)]
public function listItems(int $page = 1, int $perPage = 20): array { ... }

$this->addParameterSet(new PaginationParams());

#[PostMapping]
#[ResponseBody]
#[Validate('validateRegistration')]
#[RequestParam('password', ParamType::STRING)]
#[RequestParam('password_confirm', ParamType::STRING)]
public function register(string $password, string $passwordConfirm): array { ... }

private function validateRegistration(array $inputs): array {
    $errors = [];
    if ($inputs['password'] !== $inputs['password_confirm']) {
        $errors['password_confirm'] = 'Passwords do not match.';
    }
    return $errors; // empty = pass
}

public function validate(array $inputs): array {
    $errors = [];
    if (isset($inputs['end_date']) && $inputs['end_date'] <= $inputs['start_date']) {
        $errors['end_date'] = 'End date must be after start date.';
    }
    return $errors;
}

use WebFiori\Http\ResponseEntity;
use WebFiori\Json\Json;

#[PostMapping]
#[ResponseBody]
#[AllowAnonymous]
#[RequestParam('username', ParamType::STRING)]
#[RequestParam('password', ParamType::STRING)]
public function login(string $username, string $password): ResponseEntity {
    if ($username === 'admin' && $password === 'secret') {
        return ResponseEntity::ok(new Json(['token' => 'abc123']));
    }
    return ResponseEntity::unauthorized(new Json(['message' => 'Invalid credentials']));
}

return new ResponseEntity($body, 418, 'text/plain');


use WebFiori\Http\Test\ServiceTestCase;

class MyServiceTest extends ServiceTestCase {
    public function testGetRequest() {
        $this->get(new MyService(), [
            'param1' => 'value1',
            'param2' => 'value2'
        ])
            ->assertOk()
            ->assertJson()
            ->assertBodyContains('success');
    }
    
    public function testPostRequest() {
        $this->post(new MyService(), [
            'name' => 'John Doe',
            'email' => '[email protected]'
        ])
            ->assertOk()
            ->assertJson();
    }
}


use WebFiori\Http\WebService;
use WebFiori\Http\Annotations\RestController;
use WebFiori\Http\Annotations\GetMapping;
use WebFiori\Http\Annotations\PostMapping;
use WebFiori\Http\Annotations\PutMapping;
use WebFiori\Http\Annotations\DeleteMapping;
use WebFiori\Http\Annotations\RequestParam;
use WebFiori\Http\Annotations\ResponseBody;
use WebFiori\Http\Annotations\AllowAnonymous;
use WebFiori\Http\ParamType;

#[RestController('tasks', 'Task management service')]
class TaskService extends WebService {
    
    #[GetMapping]
    #[ResponseBody]
    #[AllowAnonymous]
    public function getTasks(): array {
        return [
            'tasks' => [
                ['id' => 1, 'title' => 'Task 1', 'completed' => false],
                ['id' => 2, 'title' => 'Task 2', 'completed' => true]
            ],
            'count' => 2
        ];
    }
    
    #[PostMapping]
    #[ResponseBody]
    #[AllowAnonymous]
    #[RequestParam('title', ParamType::STRING)]
    #[RequestParam('description', ParamType::STRING, true)]
    public function createTask(string $title, ?string $description): array {
        
        return [
            'id' => 3,
            'title' => $title,
            'description' => $description ?: '',
            'completed' => false
        ];
    }
    
    #[PutMapping]
    #[ResponseBody]
    #[AllowAnonymous]
    #[RequestParam('id', ParamType::INT)]
    #[RequestParam('title', ParamType::STRING, true)]
    public function updateTask(int $id, ?string $title): array {
        
        return [
            'id' => $id,
            'title' => $title,
            'updated_at' => date('Y-m-d H:i:s')
        ];
    }
    
    #[DeleteMapping]
    #[ResponseBody]
    #[AllowAnonymous]
    #[RequestParam('id', ParamType::INT)]
    public function deleteTask(int $id): array {
        return [
            'id' => $id,
            'deleted_at' => date('Y-m-d H:i:s')
        ];
    }
}

use WebFiori\Http\Annotations\Produces;
use WebFiori\Http\MediaType;
use WebFiori\Http\ResponseEntity;

#[GetMapping]
#[ResponseBody]
#[Produces(MediaType::JSON, MediaType::XML)]
public function getUser(int $id): ResponseEntity {
    $type = $this->getNegotiatedContentType();

    if ($type === MediaType::XML) {
        return new ResponseEntity('<user>...</user>', 200, MediaType::XML);
    }

    return ResponseEntity::ok(new Json(['id' => $id]));
}