Skip to content

Full CRUD example

Let's assume that we have designed the following API:

import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    id: int
    name: str


class CreateItem(BaseModel):
    name: str


@app.get('/')
async def list_items(offset: int = 0, limit: int = 20, q: str = None) -> list[Item]:
    raise NotImplementedError()


@app.post('/', status_code=201)
async def create_item(*, item_in: CreateItem) -> Item:
    raise NotImplementedError()


@app.get('/{uid}/')
async def get_item(*, uid: int) -> Item:
    raise NotImplementedError()


@app.put('/{uid}/')
async def update_item(*, uid: int, item_in: Item) -> Item:
    raise NotImplementedError()


@app.delete('/{uid}/', status_code=204)
async def delete_item(*, uid: int) -> None:
    raise NotImplementedError()


if __name__ == '__main__':
    uvicorn.run('example:app', reload=True)

We have prepared endpoints, described filters, chosen pagination methods, and defined the input and output data formats, but implementation is not yet ready. After the server starts, we can see the OpenAPI schema and the UI for it at http://127.0.0.1:8000/docs/. We can share the schema of our API with other teams so that they can start doing their part of the work while we implement the internal logic of our application in parallel. But there's a small problem: when we make a request to our API, it responds with an error, meaning it's not quite ready to use.

Let's have a look at the solution!

Configure mocking

Add MockAPIMiddleware middleware to app and raise APINotImplementedError in your endpoint stubs.

import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel

from fastapi_mock_middleware import MockAPIMiddleware, APINotImplementedError

app = FastAPI()
app.add_middleware(MockAPIMiddleware)


class Item(BaseModel):
    id: int
    name: str


class CreateItem(BaseModel):
    name: str


@app.get('/')
async def list_items(offset: int = 0, limit: int = 20, q: str = None) -> list[Item]:
    raise APINotImplementedError()


@app.post('/', status_code=201)
async def create_item(*, item_in: CreateItem) -> Item:
    raise APINotImplementedError()


@app.get('/{uid}/')
async def get_item(*, uid: int) -> Item:
    raise APINotImplementedError()


@app.put('/{uid}/')
async def update_item(*, uid: int, item_in: Item) -> Item:
    raise APINotImplementedError()


@app.delete('/{uid}/', status_code=204)
async def delete_item(*, uid: int) -> None:
    raise APINotImplementedError()


if __name__ == '__main__':
    uvicorn.run('example:app', reload=True)

Check it

Open your browser at http://127.0.0.1:8000/docs and try to call API using Swagger UI or use curl. All called APIs must return mocked data as a response.

  • Get list:
curl http://127.0.0.1:8000/
  • Get one:
curl http://127.0.0.1:8000/1/
  • Create:
curl -X POST http://127.0.0.1:8000/ -H 'Content-Type: application/json' -d '{
  "name": "string"
}'
  • Update:
curl -X PUT http://127.0.0.1:8000/1/ -H 'Content-Type: application/json' -d '{
  "id": 1,
  "name": "string"
}'
  • Delete
curl -X DELETE -v http://127.0.0.1:8000/1/