Skip to content

Commit

Permalink
Merge pull request #116 from RonasIT/96-add-response-schemes
Browse files Browse the repository at this point in the history
feat: add response schemas.
  • Loading branch information
DenTray authored Dec 14, 2023
2 parents 4437b15 + ddcc184 commit e939c8f
Show file tree
Hide file tree
Showing 19 changed files with 384 additions and 33 deletions.
2 changes: 1 addition & 1 deletion src/Http/Middleware/AutoDocMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function handle($request, Closure $next)
{
$response = $next($request);

if ((config('app.env') == 'testing') && !self::$skipped && !empty($request->route())) {
if ((config('app.env') === 'testing') && !self::$skipped && !empty($request->route())) {
app(SwaggerService::class)->addData($request, $response);
}

Expand Down
73 changes: 68 additions & 5 deletions src/Services/SwaggerService.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public function __construct(Container $container)

$this->setDriver();

if (config('app.env') == 'testing') {
if (config('app.env') === 'testing') {
$this->container = $container;

$this->security = $this->config['security'];
Expand Down Expand Up @@ -281,6 +281,60 @@ protected function markAsDeprecated(array $annotations)
$this->item['deprecated'] = Arr::get($annotations, 'deprecated', false);
}

protected function saveResponseSchema(?array $content, string $definition): void
{
if (empty($content)) {
return;
}

$schemaProperties = [];
$schemaType = 'object';

if (array_is_list($content)) {
$this->saveListResponseDefinitions($content, $schemaProperties);

$schemaType = 'array';
} else {
$this->saveObjectResponseDefinitions($content, $schemaProperties, $definition);
}

$this->data['definitions'][$definition] = [
'type' => $schemaType,
'properties' => $schemaProperties
];
}

protected function saveListResponseDefinitions(array $content, array &$schemaProperties): void
{
$types = [];

foreach ($content as $value) {
$type = gettype($value);

if (!in_array($type, $types)) {
$types[] = $type;
$schemaProperties['items']['allOf'][]['type'] = $type;
}
}
}

protected function saveObjectResponseDefinitions(array $content, array &$schemaProperties, string $definition): void
{
$properties = Arr::get($this->data['definitions'], $definition, []);

foreach ($content as $name => $value) {
$property = Arr::get($properties, $name, []);

if (is_null($value)) {
$property['nullable'] = true;
} else {
$property['type'] = gettype($value);
}

$schemaProperties[$name] = $property;
}
}

protected function parseResponse($response)
{
$produceList = $this->data['paths'][$this->uri][$this->method]['produces'];
Expand Down Expand Up @@ -325,6 +379,15 @@ protected function parseResponse($response)
$produce
);
}

$action = Str::ucfirst($this->getActionName($this->uri));
$definition = "{$this->method}{$action}{$code}ResponseObject";

$this->saveResponseSchema($content, $definition);

if (is_array($this->item['responses'][$code])) {
$this->item['responses'][$code]['schema']['$ref'] = "#/definitions/{$definition}";
}
}

protected function saveExample($code, $content, $produce)
Expand Down Expand Up @@ -424,7 +487,7 @@ protected function saveGetRequestParameters($rules, array $attributes, array $an
}

$existedParameter = Arr::first($this->item['parameters'], function ($existedParameter) use ($parameter) {
return $existedParameter['name'] == $parameter;
return $existedParameter['name'] === $parameter;
});

if (empty($existedParameter)) {
Expand Down Expand Up @@ -542,7 +605,7 @@ protected function requestHasBody(): bool
$parameters = $this->data['paths'][$this->uri][$this->method]['parameters'];

$bodyParamExisted = Arr::where($parameters, function ($value) {
return $value['name'] == 'body';
return $value['name'] === 'body';
});

return empty($bodyParamExisted);
Expand All @@ -552,7 +615,7 @@ public function getConcreteRequest()
{
$controller = $this->request->route()->getActionName();

if ($controller == 'Closure') {
if ($controller === 'Closure') {
return null;
}

Expand Down Expand Up @@ -735,7 +798,7 @@ protected function camelCaseToUnderScore($input): string
$ret = $matches[0];

foreach ($ret as &$match) {
$match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match);
$match = ($match === strtoupper($match)) ? strtolower($match) : lcfirst($match);
}

return implode('_', $ret);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@
}
]
}
]
],
"$ref": "#/definitions/getUsersroles200ResponseObject"
}
}
},
Expand All @@ -76,7 +77,20 @@
}
}
},
"definitions": {},
"definitions": {
"getUsersroles200ResponseObject": {
"type": "array",
"properties": {
"items": {
"allOf": [
{
"type": "array"
}
]
}
}
}
},
"info": {
"description": "This is automatically collected documentation",
"version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"description": "Forbidden",
"schema":
{
"$ref": "#/definitions/postApiusers403ResponseObject",
"example":
{
"message": "This action is unauthorized."
Expand Down Expand Up @@ -68,6 +69,14 @@
"first_name": "andrey",
"last_name": "voronin"
}
},
"postApiusers403ResponseObject": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
},
"info":
Expand Down
23 changes: 21 additions & 2 deletions tests/fixtures/SwaggerServiceTest/tmp_data_get_user_request.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@
"id": 2,
"name": "client"
}
}
},
"$ref": "#/definitions/getUsers{id}assignRole{roleId}200ResponseObject"
}
}
},
Expand All @@ -71,7 +72,25 @@
}
}
},
"definitions": {},
"definitions": {
"getUsers{id}assignRole{roleId}200ResponseObject": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"likes_count": {
"type": "integer"
},
"role": {
"type": "array"
}
}
}
},
"info": {
"description": "This is automatically collected documentation",
"version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
}
]
}
]
],
"$ref": "#/definitions/postUsers200ResponseObject"
}
}
},
Expand Down Expand Up @@ -97,6 +98,18 @@
"required": [
"query"
]
},
"postUsers200ResponseObject": {
"type": "array",
"properties": {
"items": {
"allOf": [
{
"type": "array"
}
]
}
}
}
},
"info": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@
}
]
}
]
],
"$ref": "#/definitions/postUsers200ResponseObject"
}
}
},
Expand Down Expand Up @@ -93,6 +94,18 @@
"notification_settings": "RonasIT\\Support\\Tests\\Support\\Mock\\TestNotificationSetting"
},
"required": ["query"]
},
"postUsers200ResponseObject": {
"type": "array",
"properties": {
"items": {
"allOf": [
{
"type": "array"
}
]
}
}
}
},
"info": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@
"204": {
"description": "Operation successfully done",
"schema": {
"example": null
"example": null,
"$ref": "#/definitions/patchUsers{id}204ResponseObject"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@
}
]
}
]
],
"$ref": "#/definitions/getUsersroles200ResponseObject"
}
}
},
Expand All @@ -52,7 +53,20 @@
}
}
},
"definitions": {},
"definitions": {
"getUsersroles200ResponseObject": {
"type": "array",
"properties": {
"items": {
"allOf": [
{
"type": "array"
}
]
}
}
}
},
"info": {
"description": "This is automatically collected documentation",
"version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@
}
]
}
]
],
"$ref": "#/definitions/getUsersroles200ResponseObject"
}
}
},
Expand All @@ -76,7 +77,20 @@
}
}
},
"definitions": {},
"definitions": {
"getUsersroles200ResponseObject": {
"type": "array",
"properties": {
"items": {
"allOf": [
{
"type": "array"
}
]
}
}
}
},
"info": {
"description": "This is automatically collected documentation",
"version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,20 @@
}
}
},
"definitions": {},
"definitions": {
"getUsersroles200ResponseObject": {
"type": "array",
"properties": {
"items": {
"allOf": [
{
"type": "array"
}
]
}
}
}
},
"info": {
"description": "This is automatically collected documentation",
"version": "0.0.0",
Expand Down
Loading

0 comments on commit e939c8f

Please sign in to comment.