Skip to content

REST API

Théophile MADET edited this page Oct 21, 2025 · 6 revisions

When writing views with Django's standard classes like TemplateView, FormView... we usually don't need to create API endpoints, but when writing interactive pages, usually with React, we do need them. We use the Django REST framework to create the views, drf-spectacular to create a schema file from our DRF views automatically, then openapi-generator-cli to create Typescript clients from the schema file. This is fairly complex but it helps us make sure that our the communication between frontend and backend uses the correct data format.

Write the view

Use the official DRF docs to learn how to write API views. Check tapir.welcomedesk.views.SearchMemberForWelcomeDeskView for a relatively simple example. Don't forget to add the view to the urls.py file.

Define the inputs and outputs

Annotate your view's get, post, ... methods with @extend_schema:

  • For get requests, define the URL parameters with @extend_schema(parameters=[OpenApiParameter(name="my_parameter", required=True, type=str)])
  • For post requests, define a serializer for your request's content and use @extend_schema(request=MyRequestSerializer)
  • In all cases, define the response with @extend_schema(responses={200: bool}) or @extend_schema(responses={200: MyResponseSerializer}).

This will let spectacular know exactly what the inputs and outputs of your view are so that it can create the schema file.

Update the schema file

Run scripts/generate_api_schema.sh to update the schema file (schema.yml, at the root of the repository). This file is a formalized documentation of our API endpoints.

Generate the Typescript clients

Run scripts/generate_api_clients.sh to generate the typescript clients. Those clients let us call the API endpoints defined above with precisely typed function calls.

Use the generated clients

In your React file, define a client with const welcomeDeskApi = useApi(WelcomedeskApi); (or CoopApi, ShiftsApi...). With that client, you can do calls like this:

const welcomeDeskApi = useApi(WelcomedeskApi);
api
  .welcomedeskApiSearchList(
    { searchInput: searchInput },
  )
  .then((results) => {
    // do something
  })
  .catch((error: FetchError) => {
    // log the error
  });

Clone this wiki locally