Окремі схеми OpenAPI для введення та виведення, чи ні¶
🌐 Переклад ШІ та людьми
Цей переклад виконано ШІ під керівництвом людей. 🤝
Можливі помилки через неправильне розуміння початкового змісту або неприродні формулювання тощо. 🤖
Ви можете покращити цей переклад, допомігши нам краще спрямовувати AI LLM.
Відколи вийшов Pydantic v2, згенерований OpenAPI став трохи точнішим і більш коректним, ніж раніше. 😎
Насправді подекуди буде навіть дві схеми JSON в OpenAPI для тієї самої моделі Pydantic: для введення та для виведення - залежно від наявності значень за замовчуванням.
Розгляньмо, як це працює, і як це змінити за потреби.
Моделі Pydantic для введення та виведення¶
Припустімо, у вас є модель Pydantic зі значеннями за замовчуванням, наприклад:
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
# Code below omitted 👇
👀 Full file preview
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
app = FastAPI()
@app.post("/items/")
def create_item(item: Item):
return item
@app.get("/items/")
def read_items() -> list[Item]:
return [
Item(
name="Portal Gun",
description="Device to travel through the multi-rick-verse",
),
Item(name="Plumbus"),
]
Модель для введення¶
Якщо ви використовуєте цю модель як введення, як тут:
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
app = FastAPI()
@app.post("/items/")
def create_item(item: Item):
return item
# Code below omitted 👇
👀 Full file preview
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
app = FastAPI()
@app.post("/items/")
def create_item(item: Item):
return item
@app.get("/items/")
def read_items() -> list[Item]:
return [
Item(
name="Portal Gun",
description="Device to travel through the multi-rick-verse",
),
Item(name="Plumbus"),
]
…тоді поле description не буде обов'язковим, адже воно має значення за замовчуванням None.
Модель для введення в документації¶
У документації ви побачите, що поле description не має червоної зірочки - воно не позначене як обов'язкове:
Модель для виведення¶
Але якщо ви використовуєте цю саму модель для виведення, як тут:
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
app = FastAPI()
@app.post("/items/")
def create_item(item: Item):
return item
@app.get("/items/")
def read_items() -> list[Item]:
return [
Item(
name="Portal Gun",
description="Device to travel through the multi-rick-verse",
),
Item(name="Plumbus"),
]
…тоді, оскільки description має значення за замовчуванням, якщо ви нічого не повернете для цього поля, воно все одно матиме це значення за замовчуванням.
Модель для даних відповіді при виведенні¶
Якщо ви скористаєтеся документацією та перевірите відповідь, навіть попри те, що код нічого не додав в одне з полів description, JSON-відповідь містить значення за замовчуванням (null):
Це означає, що воно завжди матиме значення - просто іноді це значення може бути None (або null у JSON).
Отже, клієнтам, які використовують ваш API, не потрібно перевіряти, чи існує значення - вони можуть припустити, що поле завжди буде присутнє, але в окремих випадках воно матиме значення за замовчуванням None.
У OpenAPI це описується тим, що поле позначається як обов'язкове, адже воно завжди присутнє.
Тому Схема JSON для моделі може відрізнятися залежно від того, чи використовується вона для введення або виведення:
- для введення description не буде обов'язковим
- для виведення воно буде обов'язковим (і можливо None, або в термінах JSON - null)
Модель для виведення в документації¶
У документації ви також можете перевірити модель для виведення: і name, і description позначені як обов'язкові червоною зірочкою:
Модель для введення та виведення в документації¶
Якщо відкрити всі наявні Схеми (схеми JSON) в OpenAPI, то ви побачите дві: Item-Input і Item-Output.
Для Item-Input поле description не є обов'язковим - червоної зірочки немає.
А для Item-Output description є обов'язковим - є червона зірочка.
Завдяки цій можливості у Pydantic v2 ваша документація API стає більш точною, а якщо у вас є згенеровані клієнти та SDK, вони також будуть точнішими - з кращим досвідом розробника та узгодженістю. 🎉
Не розділяти схеми¶
Втім іноді може знадобитися мати одну й ту саму схему для введення та виведення.
Основний випадок - коли у вас вже є згенерований клієнтський код/SDK, і ви поки не бажаєте оновлювати весь такий згенерований код/SDK. Ймовірно, ви зробите це пізніше, але не зараз.
У такому разі ви можете вимкнути цю можливість у FastAPI параметром separate_input_output_schemas=False.
Інформація
Підтримку separate_input_output_schemas додано у FastAPI 0.102.0. 🤓
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
app = FastAPI(separate_input_output_schemas=False)
@app.post("/items/")
def create_item(item: Item):
return item
@app.get("/items/")
def read_items() -> list[Item]:
return [
Item(
name="Portal Gun",
description="Device to travel through the multi-rick-verse",
),
Item(name="Plumbus"),
]
Одна схема для моделей введення та виведення в документації¶
Тепер для цієї моделі буде лише одна спільна схема для введення та виведення - тільки Item, і в ній description буде не обов'язковим: