Core concepts¶
To learn django-modern-rest you have to learn just a couple of things:
- Endpoint¶
Endpointis a single API route. It is defined by its name – HTTP method – and its Metadata, what response schema it returns, what status codes it can return, etc. Each endpoint might have different Component types for parsing the inputs.- Controller¶
Controlleris a collection of one or more endpoints with the same set of components. Controller is a subclass ofView, so it can be used in a routing directly.- Component¶
Controllers parse data via components like
BodyorHeaders. You can write your own components.- Metadata¶
A collection of all the things each Endpoint accepts and returns. It is used for request parsing, response validation, and OpenAPI schema.
- Serializer¶
BaseSerializersubclass that knows how to load and dump raw data into models. We have 2 bundled serializers in plugins: forpydanticandmsgspec, you can write your own serializers for other libraries.- Routing¶
Routing is a mapping of URLs to controllers. We use default Django’s URL routing. Controllers might have many URLs, for example:
/api/v1/users/and/api/v2/users/
Example:
1import uuid
2
3import msgspec
4
5from dmr import Body, Controller, NewHeader, modify
6from dmr.plugins.msgspec import MsgspecSerializer
7
8
9class UserCreateModel(msgspec.Struct):
10 email: str
11
12
13class UserModel(UserCreateModel):
14 uid: uuid.UUID
15
16
17class UserController( # <- `Controller` definition
18 Controller[MsgspecSerializer], # <- Passing `Serializer`
19):
20 @modify(headers={'X-Default': NewHeader(value='1')}) # <- extra `Metadata`
21 def post(
22 self,
23 parsed_body: Body[UserCreateModel],
24 ) -> UserModel: # <- `Endpoint` definition
25 return UserModel(uid=uuid.uuid4(), email=parsed_body.email)
26
Run result
$ curl http://127.0.0.1:8000/api/user/ -D - -X POST -d '{"email": "user@wms.org"}' -H 'Content-Type: application/json'
HTTP/1.1 201 Created
date: Sun, 29 Mar 2026 18:52:44 GMT
server: uvicorn
Content-Type: application/json
X-Default: 1
X-Frame-Options: DENY
Vary: Accept-Language
Content-Language: en
Content-Length: 69
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin
{"email":"user@wms.org","uid":"2f5a9fd4-3ab1-4e76-b266-bcc152d279cb"}
Async vs Sync¶
We support both Django modes: sync and async, the same way regular Django supports them.
We don’t do anything special with the async mode, so any existing
guides, tools, deployment strategies should
just work with django-modern-rest if they work for Django.
Maximum integration with Django¶
We try to keep Django compatibility as our main goal. Everything should work by default, starting from django-cors-headers up to django-ratelimit.
We also provide Middleware wrapper tools to convert any middleware
response to the required API schema and set needed Content-Type, etc.
We support all existing mixins: because
Controller is a subclass
of Django’s django.views.generic.base.View class.
We support all existing decorators: because we have
endpoint_decorator()
and dispatch_decorator() utilities
that can decorate endpoints and controllers.
Works best with django-stubs. Read next: our Integrations guide.
Next up¶
Learn how controllers work.
Learn how to configure django-modern-rest.