Skip to content

Commit 45ce9e1

Browse files
committed
Added standard error responses. Added response_errors for routers.
1 parent 1ea1725 commit 45ce9e1

File tree

32 files changed

+783
-229
lines changed

32 files changed

+783
-229
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ FastOpenAPI follows the [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
99
### Added
1010
- `AioHttpRouter` for integration with the `AioHttp` framework
1111
- Class-level cache for model schemas
12+
- `response_errors` for routers
13+
- `error_handler` for standard error responses
1214

1315
## [0.4.0] - 2025-03-20
1416

examples/aiohttp/app/api/v1/authors.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,58 @@
1515
router = AioHttpRouter()
1616

1717

18-
@router.post("/authors", tags=["Authors"], status_code=201, response_model=AuthorSchema)
18+
@router.post(
19+
"/authors",
20+
tags=["Authors"],
21+
status_code=201,
22+
response_errors=[400, 422, 500],
23+
response_model=AuthorSchema,
24+
)
1925
async def create_author(body: CreateAuthorSchema) -> AuthorSchema:
2026
return await author_service.create_author(body)
2127

2228

23-
@router.get("/authors/{author_id}", tags=["Authors"], response_model=AuthorSchema)
29+
@router.get(
30+
"/authors/{author_id}",
31+
tags=["Authors"],
32+
response_errors=[400, 404, 500],
33+
response_model=AuthorSchema,
34+
)
2435
async def get_author(author_id: int) -> AuthorSchema:
2536
author = await author_service.get_author(author_id)
2637
if not author:
2738
raise web.HTTPNotFound(reason="Author not found")
2839
return author
2940

3041

31-
@router.get("/authors/", tags=["Authors"], response_model=list[AuthorSchema])
42+
@router.get(
43+
"/authors/",
44+
tags=["Authors"],
45+
response_errors=[500],
46+
response_model=list[AuthorSchema],
47+
)
3248
async def get_authors(body: FilterAuthorSchema) -> list[AuthorSchema]:
3349
return await author_service.get_authors(body)
3450

3551

36-
@router.delete("/authors/{author_id}", tags=["Authors"], status_code=204)
52+
@router.delete(
53+
"/authors/{author_id}",
54+
tags=["Authors"],
55+
status_code=204,
56+
response_errors=[400, 404, 500],
57+
)
3758
async def delete_author(author_id: int) -> None:
3859
author = await author_service.delete_author(author_id)
3960
if not author:
4061
raise web.HTTPNotFound(reason="Author not found")
4162

4263

43-
@router.patch("/authors/{author_id}", tags=["Authors"], response_model=AuthorSchema)
64+
@router.patch(
65+
"/authors/{author_id}",
66+
tags=["Authors"],
67+
response_errors=[400, 404, 422, 500],
68+
response_model=AuthorSchema,
69+
)
4470
async def update_author(author_id: int, body: UpdateAuthorSchema) -> AuthorSchema:
4571
author = await author_service.update_author(author_id, body)
4672
if not author:

examples/aiohttp/app/api/v1/posts.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,52 @@
1414
router = AioHttpRouter()
1515

1616

17-
@router.post("/posts", tags=["Posts"], status_code=201, response_model=PostSchema)
17+
@router.post(
18+
"/posts",
19+
tags=["Posts"],
20+
status_code=201,
21+
response_errors=[400, 422, 500],
22+
response_model=PostSchema,
23+
)
1824
async def create_post(body: CreatePostSchema) -> PostSchema:
1925
return await post_service.create_post(body)
2026

2127

22-
@router.get("/posts/{post_id}", tags=["Posts"], response_model=PostSchema)
28+
@router.get(
29+
"/posts/{post_id}",
30+
tags=["Posts"],
31+
response_errors=[400, 404, 500],
32+
response_model=PostSchema,
33+
)
2334
async def get_post(post_id: int) -> PostSchema:
2435
post = await post_service.get_post(post_id)
2536
if not post:
2637
raise web.HTTPNotFound(reason="Author not found")
2738
return post
2839

2940

30-
@router.get("/posts/", tags=["Posts"], response_model=list[PostSchema])
41+
@router.get(
42+
"/posts/", tags=["Posts"], response_errors=[500], response_model=list[PostSchema]
43+
)
3144
async def get_posts(body: FilterPostSchema) -> list[PostSchema]:
3245
return await post_service.get_posts(body)
3346

3447

35-
@router.delete("/posts/{post_id}", tags=["Posts"], status_code=204)
48+
@router.delete(
49+
"/posts/{post_id}", tags=["Posts"], status_code=204, response_errors=[400, 404, 500]
50+
)
3651
async def delete_post(post_id: int) -> None:
3752
post = await post_service.delete_post(post_id)
3853
if not post:
3954
raise web.HTTPNotFound(reason="Post not found")
4055

4156

42-
@router.patch("/posts/{post_id}", tags=["Posts"], response_model=PostSchema)
57+
@router.patch(
58+
"/posts/{post_id}",
59+
tags=["Posts"],
60+
response_errors=[400, 404, 422, 500],
61+
response_model=PostSchema,
62+
)
4363
async def update_post(post_id: int, body: UpdatePostSchema) -> PostSchema:
4464
post = await post_service.update_post(post_id, body)
4565
if not post:

examples/falcon/app/api/v1/authors.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,58 @@
1515
router = FalconRouter()
1616

1717

18-
@router.post("/authors", tags=["Authors"], status_code=201, response_model=AuthorSchema)
18+
@router.post(
19+
"/authors",
20+
tags=["Authors"],
21+
status_code=201,
22+
response_errors=[400, 422, 500],
23+
response_model=AuthorSchema,
24+
)
1925
async def create_author(body: CreateAuthorSchema) -> AuthorSchema:
2026
return await author_service.create_author(body)
2127

2228

23-
@router.get("/authors/{author_id}", tags=["Authors"], response_model=AuthorSchema)
29+
@router.get(
30+
"/authors/{author_id}",
31+
tags=["Authors"],
32+
response_errors=[400, 404, 500],
33+
response_model=AuthorSchema,
34+
)
2435
async def get_author(author_id: int) -> AuthorSchema:
2536
author = await author_service.get_author(author_id)
2637
if not author:
2738
raise falcon.HTTPNotFound()
2839
return author
2940

3041

31-
@router.get("/authors/", tags=["Authors"], response_model=list[AuthorSchema])
42+
@router.get(
43+
"/authors/",
44+
tags=["Authors"],
45+
response_errors=[500],
46+
response_model=list[AuthorSchema],
47+
)
3248
async def get_authors(body: FilterAuthorSchema) -> list[AuthorSchema]:
3349
return await author_service.get_authors(body)
3450

3551

36-
@router.delete("/authors/{author_id}", tags=["Authors"], status_code=204)
52+
@router.delete(
53+
"/authors/{author_id}",
54+
tags=["Authors"],
55+
status_code=204,
56+
response_errors=[400, 404, 500],
57+
)
3758
async def delete_author(author_id: int) -> None:
3859
author = await author_service.delete_author(author_id)
3960
if not author:
4061
raise falcon.HTTPNotFound()
4162

4263

43-
@router.patch("/authors/{author_id}", tags=["Authors"], response_model=AuthorSchema)
64+
@router.patch(
65+
"/authors/{author_id}",
66+
tags=["Authors"],
67+
response_errors=[400, 404, 422, 500],
68+
response_model=AuthorSchema,
69+
)
4470
async def update_author(author_id: int, body: UpdateAuthorSchema) -> AuthorSchema:
4571
author = await author_service.update_author(author_id, body)
4672
if not author:

examples/falcon/app/api/v1/posts.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,52 @@
1414
router = FalconRouter()
1515

1616

17-
@router.post("/posts", tags=["Posts"], status_code=201, response_model=PostSchema)
17+
@router.post(
18+
"/posts",
19+
tags=["Posts"],
20+
status_code=201,
21+
response_errors=[400, 422, 500],
22+
response_model=PostSchema,
23+
)
1824
async def create_post(body: CreatePostSchema) -> PostSchema:
1925
return await post_service.create_post(body)
2026

2127

22-
@router.get("/posts/{post_id}", tags=["Posts"], response_model=PostSchema)
28+
@router.get(
29+
"/posts/{post_id}",
30+
tags=["Posts"],
31+
response_errors=[400, 404, 500],
32+
response_model=PostSchema,
33+
)
2334
async def get_post(post_id: int) -> PostSchema:
2435
post = await post_service.get_post(post_id)
2536
if not post:
2637
raise falcon.HTTPNotFound()
2738
return post
2839

2940

30-
@router.get("/posts/", tags=["Posts"], response_model=list[PostSchema])
41+
@router.get(
42+
"/posts/", tags=["Posts"], response_errors=[500], response_model=list[PostSchema]
43+
)
3144
async def get_posts(body: FilterPostSchema) -> list[PostSchema]:
3245
return await post_service.get_posts(body)
3346

3447

35-
@router.delete("/posts/{post_id}", tags=["Posts"], status_code=204)
48+
@router.delete(
49+
"/posts/{post_id}", tags=["Posts"], status_code=204, response_errors=[400, 404, 500]
50+
)
3651
async def delete_post(post_id: int) -> None:
3752
post = await post_service.delete_post(post_id)
3853
if not post:
3954
raise falcon.HTTPNotFound()
4055

4156

42-
@router.patch("/posts/{post_id}", tags=["Posts"], response_model=PostSchema)
57+
@router.patch(
58+
"/posts/{post_id}",
59+
tags=["Posts"],
60+
response_errors=[400, 404, 422, 500],
61+
response_model=PostSchema,
62+
)
4363
async def update_post(post_id: int, body: UpdatePostSchema) -> PostSchema:
4464
post = await post_service.update_post(post_id, body)
4565
if not post:

examples/flask/app/api/v1/authors.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,59 @@
1717
router = FlaskRouter()
1818

1919

20-
@router.post("/authors", tags=["Authors"], status_code=201, response_model=AuthorSchema)
20+
@router.post(
21+
"/authors",
22+
tags=["Authors"],
23+
status_code=201,
24+
response_errors=[400, 422, 500],
25+
response_model=AuthorSchema,
26+
)
2127
def create_author(body: CreateAuthorSchema) -> AuthorSchema:
2228
return author_service.create_author(body)
2329

2430

25-
@router.get("/authors/{author_id}", tags=["Authors"], response_model=AuthorSchema)
31+
@router.get(
32+
"/authors/{author_id}",
33+
tags=["Authors"],
34+
response_errors=[400, 404, 500],
35+
response_model=AuthorSchema,
36+
)
2637
def get_author(author_id: int) -> AuthorSchema:
2738
author = author_service.get_author(author_id)
2839
if not author:
2940
abort(HTTPStatus.NOT_FOUND)
3041
return author
3142

3243

33-
@router.get("/authors/", tags=["Authors"], response_model=list[AuthorSchema])
44+
@router.get(
45+
"/authors/",
46+
tags=["Authors"],
47+
response_errors=[500],
48+
response_model=list[AuthorSchema],
49+
)
3450
def get_authors(body: FilterAuthorSchema) -> list[AuthorSchema]:
3551
return author_service.get_authors(body)
3652

3753

38-
@router.delete("/authors/{author_id}", tags=["Authors"], status_code=204)
54+
@router.delete(
55+
"/authors/{author_id}",
56+
tags=["Authors"],
57+
status_code=204,
58+
response_errors=[400, 404, 500],
59+
)
3960
def delete_author(author_id: int) -> None:
4061
author = author_service.delete_author(author_id)
4162
if not author:
4263
abort(HTTPStatus.NOT_FOUND)
4364
return None
4465

4566

46-
@router.patch("/authors/{author_id}", tags=["Authors"], response_model=AuthorSchema)
67+
@router.patch(
68+
"/authors/{author_id}",
69+
tags=["Authors"],
70+
response_errors=[400, 404, 422, 500],
71+
response_model=AuthorSchema,
72+
)
4773
def update_author(author_id: int, body: UpdateAuthorSchema) -> AuthorSchema:
4874
author = author_service.update_author(author_id, body)
4975
if not author:

examples/flask/app/api/v1/posts.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,52 @@
1616
router = FlaskRouter()
1717

1818

19-
@router.post("/posts", tags=["Posts"], status_code=201, response_model=PostSchema)
19+
@router.post(
20+
"/posts",
21+
tags=["Posts"],
22+
status_code=201,
23+
response_errors=[400, 422, 500],
24+
response_model=PostSchema,
25+
)
2026
def create_post(body: CreatePostSchema) -> PostSchema:
2127
return post_service.create_post(body)
2228

2329

24-
@router.get("/posts/{post_id}", tags=["Posts"], response_model=PostSchema)
30+
@router.get(
31+
"/posts/{post_id}",
32+
tags=["Posts"],
33+
response_errors=[400, 404, 500],
34+
response_model=PostSchema,
35+
)
2536
def get_post(post_id: int) -> PostSchema:
2637
post = post_service.get_post(post_id)
2738
if not post:
2839
abort(HTTPStatus.NOT_FOUND)
2940
return post
3041

3142

32-
@router.get("/posts/", tags=["Posts"], response_model=list[PostSchema])
43+
@router.get(
44+
"/posts/", tags=["Posts"], response_errors=[500], response_model=list[PostSchema]
45+
)
3346
def get_posts(body: FilterPostSchema) -> list[PostSchema]:
3447
return post_service.get_posts(body)
3548

3649

37-
@router.delete("/posts/{post_id}", tags=["Posts"], status_code=204)
50+
@router.delete(
51+
"/posts/{post_id}", tags=["Posts"], status_code=204, response_errors=[400, 404, 500]
52+
)
3853
def delete_post(post_id: int) -> None:
3954
post = post_service.delete_post(post_id)
4055
if not post:
4156
abort(HTTPStatus.NOT_FOUND)
4257

4358

44-
@router.patch("/posts/{post_id}", tags=["Posts"], response_model=PostSchema)
59+
@router.patch(
60+
"/posts/{post_id}",
61+
tags=["Posts"],
62+
response_errors=[400, 404, 422, 500],
63+
response_model=PostSchema,
64+
)
4565
def update_post(post_id: int, body: UpdatePostSchema) -> PostSchema:
4666
post = post_service.update_post(post_id, body)
4767
if not post:

0 commit comments

Comments
 (0)