API: Update index response codes and api descriptions

This commit is contained in:
Igor Scheller 2023-07-31 00:26:19 +02:00 committed by Michael Weimann
parent ef3bd7c319
commit 1a250dc250
4 changed files with 55 additions and 11 deletions

View File

@ -125,13 +125,14 @@ $route->addGroup(
$route->get('/rooms/{room_id:\d+}/shifts', 'Api\ShiftsController@entriesByRoom'); $route->get('/rooms/{room_id:\d+}/shifts', 'Api\ShiftsController@entriesByRoom');
$route->addRoute( $route->addRoute(
['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD'], ['POST', 'PUT', 'DELETE', 'PATCH'],
'/[{resource:.+}]', '/[{resource:.+}]',
'Api\IndexController@notImplemented' 'Api\IndexController@notImplemented'
); );
$route->get('/[{resource:.+}]', 'Api\IndexController@notFound');
} }
); );
$route->get('/[{resource:.+}]', 'Api\IndexController@notImplemented'); $route->get('/[{resource:.+}]', 'Api\IndexController@notFound');
} }
); );

View File

@ -46,7 +46,13 @@ components:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/Error' $ref: '#/components/schemas/Error'
NotImplementedError: # 501 NotFoundError: # 404
description: This resource can not be found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotImplementedError: # 405
description: This endpoint or method is not implemented description: This endpoint or method is not implemented
content: content:
application/json: application/json:
@ -68,7 +74,8 @@ components:
example: Meta-Group of all registered Angels example: Meta-Group of all registered Angels
url: url:
type: string type: string
example: https://example.com/news/42 example: https://example.com/angeltype/42
description: Link to the page of the given angeltype.
required: required:
- id - id
- name - name
@ -93,6 +100,9 @@ components:
example: | example: |
The first introduction meeting takes place at the **Foo Hall** at 13:37. The first introduction meeting takes place at the **Foo Hall** at 13:37.
Please bring your own seating as it might take some time. Please bring your own seating as it might take some time.
description: |
The complete news text with markdown formatting.
Might include a `[more]` tag to be used as a separator which must be removed from the text when shown.
is_meeting: is_meeting:
type: boolean type: boolean
example: true example: true
@ -119,6 +129,7 @@ components:
url: url:
type: string type: string
example: https://example.com/news/42 example: https://example.com/news/42
description: Direct link to the news page
required: required:
- id - id
- title - title
@ -141,6 +152,7 @@ components:
url: url:
type: string type: string
example: https://example.com/rooms/42 example: https://example.com/rooms/42
description: Link of the room start page
required: required:
- id - id
- name - name
@ -157,6 +169,9 @@ components:
description: description:
type: string type: string
example: You clean up the venue after the event, its fun, we promise! example: You clean up the venue after the event, its fun, we promise!
description: |
Shift description, should be added to the shift type description as it might be empty.
Normally contains additional information for a specific shift / task.
start: start:
type: string type: string
format: date-time format: date-time
@ -191,6 +206,7 @@ components:
url: url:
type: string type: string
example: https://example.com/shifts/42 example: https://example.com/shifts/42
description: Direct link of the shift
required: required:
- id - id
- title - title
@ -259,6 +275,7 @@ components:
type: string type: string
nullable: true nullable: true
example: They/Them example: They/Them
description: Should be displayed where possible to allow users to be addressed properly
contact: contact:
type: object type: object
properties: properties:
@ -266,6 +283,7 @@ components:
type: string type: string
nullable: true nullable: true
example: 4242 example: 4242
description: The DECT number is a short internal number where users can be easily reached
mobile: mobile:
type: string type: string
nullable: true nullable: true
@ -273,6 +291,7 @@ components:
url: url:
type: string type: string
example: https://example.com/users/42 example: https://example.com/users/42
description: Links to the users profile page
required: required:
- id - id
- name - name
@ -357,14 +376,14 @@ paths:
- name: id - name: id
in: path in: path
required: true required: true
description: the room identifier description: The rooms identifier
example: 42 example: 42
schema: schema:
type: integer type: integer
get: get:
tags: tags:
- shift - shift
summary: Get all shifts in the room summary: Get all shifts in the requested room
responses: responses:
'200': '200':
description: Ok description: Ok
@ -381,3 +400,5 @@ paths:
$ref: '#/components/responses/UnauthorizedError' $ref: '#/components/responses/UnauthorizedError'
'403': '403':
$ref: '#/components/responses/ForbiddenError' $ref: '#/components/responses/ForbiddenError'
'404':
$ref: '#/components/responses/NotFoundError'

View File

@ -49,15 +49,23 @@ class IndexController extends ApiController
{ {
// Respond to browser preflight options requests // Respond to browser preflight options requests
return $this->response return $this->response
->setStatusCode(204) ->setStatusCode(200)
->withHeader('allow', 'OPTIONS, HEAD, GET') ->withHeader('allow', 'OPTIONS, HEAD, GET')
->withHeader('access-control-allow-headers', 'Authorization'); ->withHeader('access-control-allow-headers', 'Authorization');
} }
public function notFound(): Response
{
return $this->response
->setStatusCode(404)
->withContent(json_encode(['message' => 'Not implemented']));
}
public function notImplemented(): Response public function notImplemented(): Response
{ {
return $this->response return $this->response
->setStatusCode(501) ->setStatusCode(405)
->withContent(json_encode(['error' => 'Not implemented'])); ->withHeader('allow', 'GET')
->withContent(json_encode(['message' => 'Method not implemented']));
} }
} }

View File

@ -51,11 +51,24 @@ class IndexControllerTest extends ApiBaseControllerTest
$controller = new IndexController(new Response(), $this->url); $controller = new IndexController(new Response(), $this->url);
$response = $controller->options(); $response = $controller->options();
$this->assertEquals(204, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
$this->assertNotEmpty($response->getHeader('allow')); $this->assertNotEmpty($response->getHeader('allow'));
$this->assertNotEmpty($response->getHeader('access-control-allow-headers')); $this->assertNotEmpty($response->getHeader('access-control-allow-headers'));
} }
/**
* @covers \Engelsystem\Controllers\Api\IndexController::notFound
*/
public function testNotFound(): void
{
$controller = new IndexController(new Response(), $this->url);
$response = $controller->notFound();
$this->assertEquals(404, $response->getStatusCode());
$this->assertEquals(['application/json'], $response->getHeader('content-type'));
$this->assertJson($response->getContent());
}
/** /**
* @covers \Engelsystem\Controllers\Api\IndexController::notImplemented * @covers \Engelsystem\Controllers\Api\IndexController::notImplemented
*/ */
@ -64,7 +77,8 @@ class IndexControllerTest extends ApiBaseControllerTest
$controller = new IndexController(new Response(), $this->url); $controller = new IndexController(new Response(), $this->url);
$response = $controller->notImplemented(); $response = $controller->notImplemented();
$this->assertEquals(501, $response->getStatusCode()); $this->assertEquals(405, $response->getStatusCode());
$this->assertEquals(['GET'], $response->getHeader('allow'));
$this->assertEquals(['application/json'], $response->getHeader('content-type')); $this->assertEquals(['application/json'], $response->getHeader('content-type'));
$this->assertJson($response->getContent()); $this->assertJson($response->getContent());
} }