Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,36 @@ public function getData(int $id, ?string $name): array {
}
```

### Reusable Parameter Sets

Implement the `ParameterSet` interface to group related parameters:

```php
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],
];
}
}
```

Use with attributes:

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

Or traditionally:

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

## Dynamic Status Codes with ResponseEntity

The `ResponseEntity` class allows `#[ResponseBody]` methods to return different HTTP status codes based on runtime logic:
Expand Down
21 changes: 21 additions & 0 deletions WebFiori/Http/Annotations/UseParameterSet.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

/**
* This file is licensed under MIT License.
*
* Copyright (c) 2026-present WebFiori Framework
*
* For more information on the license, please visit:
* https://github.com/WebFiori/.github/blob/main/LICENSE
*/
namespace WebFiori\Http\Annotations;

use Attribute;

#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
class UseParameterSet {
public function __construct(
public readonly string $class
) {
}
}
72 changes: 9 additions & 63 deletions WebFiori/Http/OpenAPI/HeaderObj.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
*
* @see https://spec.openapis.org/oas/v3.1.0#header-object
*/
class HeaderObj implements JsonI {
class HeaderObj extends OpenAPIObject implements JsonI {
/**
* Specifies that the header is deprecated and SHOULD be transitioned out of usage.
*
Expand All @@ -36,15 +36,6 @@ class HeaderObj implements JsonI {
* @var bool
*/
private bool $deprecated = false;
/**
* A brief description of the header.
*
* This could contain examples of use.
* CommonMark syntax MAY be used for rich text representation.
*
* @var string|null
*/
private ?string $description = null;

/**
* Example of the header's potential value.
Expand Down Expand Up @@ -101,15 +92,6 @@ public function getDeprecated(): bool {
return $this->deprecated;
}

/**
* Returns the description.
*
* @return string|null Returns the value, or null if not set.
*/
public function getDescription(): ?string {
return $this->description;
}

/**
* Returns the example.
*
Expand Down Expand Up @@ -190,19 +172,6 @@ public function setDeprecated(bool $deprecated): HeaderObj {
return $this;
}

/**
* Sets the description of the header.
*
* @param string $description A brief description of the header.
*
* @return HeaderObj Returns self for method chaining.
*/
public function setDescription(string $description): HeaderObj {
$this->description = $description;

return $this;
}

/**
* Sets an example of the header's potential value.
*
Expand Down Expand Up @@ -289,37 +258,14 @@ public function setStyle(string $style): HeaderObj {
public function toJSON(): Json {
$json = new Json();

if ($this->getDescription() !== null) {
$json->add('description', $this->getDescription());
}

if ($this->getRequired()) {
$json->add('required', $this->getRequired());
}

if ($this->getDeprecated()) {
$json->add('deprecated', $this->getDeprecated());
}

if ($this->getStyle() !== null) {
$json->add('style', $this->getStyle());
}

if ($this->getExplode() !== null) {
$json->add('explode', $this->getExplode());
}

if ($this->getSchema() !== null) {
$json->add('schema', $this->getSchema());
}

if ($this->getExample() !== null) {
$json->add('example', $this->getExample());
}

if ($this->getExamples() !== null) {
$json->add('examples', $this->getExamples());
}
$this->addIfNotNull($json, 'description', $this->getDescription());
$this->addIfTruthy($json, 'required', $this->getRequired());
$this->addIfTruthy($json, 'deprecated', $this->getDeprecated());
$this->addIfNotNull($json, 'style', $this->getStyle());
$this->addIfNotNull($json, 'explode', $this->getExplode());
$this->addIfNotNull($json, 'schema', $this->getSchema());
$this->addIfNotNull($json, 'example', $this->getExample());
$this->addIfNotNull($json, 'examples', $this->getExamples());

return $json;
}
Expand Down
58 changes: 58 additions & 0 deletions WebFiori/Http/OpenAPI/OpenAPIObject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

/**
* This file is licensed under MIT License.
*
* Copyright (c) 2026-present WebFiori Framework
*
* For more information on the license, please visit:
* https://github.com/WebFiori/http/blob/master/LICENSE
*/
namespace WebFiori\Http\OpenAPI;

use WebFiori\Json\Json;

/**
* Base class for OpenAPI specification objects.
*
* Provides common properties (description, deprecated, etc.) and a helper
* for building JSON output without repetitive null-checks.
*
* @author Ibrahim
*/
abstract class OpenAPIObject {
private ?string $description = null;

public function getDescription() : ?string {
return $this->description;
}

public function setDescription(string $description) : static {
$this->description = $description;
return $this;
}
/**
* Adds a value to a Json object only if it is not null.
*
* @param Json $json The target Json object.
* @param string $key The JSON key.
* @param mixed $value The value to add.
*/
protected function addIfNotNull(Json $json, string $key, mixed $value) : void {
if ($value !== null) {
$json->add($key, $value);
}
}
/**
* Adds a value to a Json object only if it is truthy (non-null, non-false, non-empty).
*
* @param Json $json The target Json object.
* @param string $key The JSON key.
* @param mixed $value The value to add.
*/
protected function addIfTruthy(Json $json, string $key, mixed $value) : void {
if (!empty($value)) {
$json->add($key, $value);
}
}
}
83 changes: 11 additions & 72 deletions WebFiori/Http/OpenAPI/ParameterObj.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
*
* @see https://spec.openapis.org/oas/v3.1.0#parameter-object
*/
class ParameterObj implements JsonI {
class ParameterObj extends OpenAPIObject implements JsonI {
/**
* If true, clients MAY pass a zero-length string value in place of parameters
* that would otherwise be omitted entirely.
Expand Down Expand Up @@ -58,16 +58,6 @@ class ParameterObj implements JsonI {
*/
private bool $deprecated = false;

/**
* A brief description of the parameter.
*
* This could contain examples of use.
* CommonMark syntax MAY be used for rich text representation.
*
* @var string|null
*/
private ?string $description = null;

/**
* Example of the parameter's potential value.
*
Expand Down Expand Up @@ -176,15 +166,6 @@ public function getDeprecated(): bool {
return $this->deprecated;
}

/**
* Returns the description.
*
* @return string|null Returns the value, or null if not set.
*/
public function getDescription(): ?string {
return $this->description;
}

/**
* Returns the example.
*
Expand Down Expand Up @@ -325,19 +306,6 @@ public function setDeprecated(bool $deprecated): ParameterObj {
return $this;
}

/**
* Sets the description of the parameter.
*
* @param string $description A brief description of the parameter.
*
* @return ParameterObj Returns self for method chaining.
*/
public function setDescription(string $description): ParameterObj {
$this->description = $description;

return $this;
}

/**
* Sets an example of the parameter's potential value.
*
Expand Down Expand Up @@ -457,45 +425,16 @@ public function toJSON(): Json {
'in' => $this->getIn()
]);

if ($this->getDescription() !== null) {
$json->add('description', $this->getDescription());
}

if ($this->getRequired()) {
$json->add('required', $this->getRequired());
}

if ($this->getDeprecated()) {
$json->add('deprecated', $this->getDeprecated());
}

if ($this->getAllowEmptyValue()) {
$json->add('allowEmptyValue', $this->getAllowEmptyValue());
}

if ($this->getStyle() !== null) {
$json->add('style', $this->getStyle());
}

if ($this->getExplode() !== null) {
$json->add('explode', $this->getExplode());
}

if ($this->getAllowReserved() !== null) {
$json->add('allowReserved', $this->getAllowReserved());
}

if ($this->getSchema() !== null) {
$json->add('schema', $this->getSchema());
}

if ($this->getExample() !== null) {
$json->add('example', $this->getExample());
}

if ($this->getExamples() !== null) {
$json->add('examples', $this->getExamples());
}
$this->addIfNotNull($json, 'description', $this->getDescription());
$this->addIfTruthy($json, 'required', $this->getRequired());
$this->addIfTruthy($json, 'deprecated', $this->getDeprecated());
$this->addIfTruthy($json, 'allowEmptyValue', $this->getAllowEmptyValue());
$this->addIfNotNull($json, 'style', $this->getStyle());
$this->addIfNotNull($json, 'explode', $this->getExplode());
$this->addIfNotNull($json, 'allowReserved', $this->getAllowReserved());
$this->addIfNotNull($json, 'schema', $this->getSchema());
$this->addIfNotNull($json, 'example', $this->getExample());
$this->addIfNotNull($json, 'examples', $this->getExamples());

return $json;
}
Expand Down
31 changes: 31 additions & 0 deletions WebFiori/Http/ParameterSet.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

/**
* This file is licensed under MIT License.
*
* Copyright (c) 2026-present WebFiori Framework
*
* For more information on the license, please visit:
* https://github.com/WebFiori/http/blob/master/LICENSE
*/
namespace WebFiori\Http;

/**
* Interface for grouping related request parameters into reusable sets.
*
* Implement this interface to define a collection of parameters that can
* be shared across multiple web services.
*
* @author Ibrahim
*/
interface ParameterSet {
/**
* Returns an array of parameter definitions.
*
* Each key is the parameter name and the value is an associative array
* of options compatible with WebService::addParameters().
*
* @return array<string, array> Parameter definitions keyed by name.
*/
public function getParameters(): array;
}
Loading
Loading