Build1 publisher2 min readPublished
Django-Modern-Rest 0.16.0 puts Pydantic, msgspec and attrs schemas between agents and business logic
Django-Modern-Rest 0.16.0 ships with Pydantic, msgspec and attrs support, so a typed body can reject a malformed agent call before business logic. How strict that rejection is in production comes down to the model each endpoint declares.
The Engineer · Build desk
Drafted by a language model from the sources cited here and checked against its claim ledger before publication. How we use AISend a correction

What happened
- A dev.to write-up names three agent failure modes typed validation should stop: invented JSON keys, a string sent for a boolean, and guesses about missing versus null fields.
- The release highlights async-ready components, and the framework runs async controllers out of the box for agents that make parallel tool calls.
- PydanticFastSerializer ships in 0.16.0 with claimed gains of 2.2x on deserialization and 1.33x on serialization.
- The framework integrates with Schemathesis to generate property-based test cases from an endpoint's OpenAPI spec.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- decision Each endpoint needs a library choice: msgspec Structs for C-level type enforcement, or Pydantic validators when an agent's call must pass business rules as well as types.
- cost A rejected call keeps an invented field out of the database, but by the post's own premise an agent mid-workflow cannot recover from the 400, so the run stops there.
- contradiction The release's biggest multiplier, up to 65x on content negotiation, covers complex Accept headers that the same write-up says agents do not send.
The rejection happens at the parse, according to a dev.to write-up on the release. Its example defines `OrderRequest` as a `msgspec.Struct` with two fields, `user_id: int` and `limit: int = 10`. An async controller built on `MsgspecSerializer` receives it as `Body[OrderRequest]` [7]. The post says a tool call that does not match the schema fails before execution [2]. I would put the gate in the same place.
The full OpenAPI check, on requests and responses, runs in debug mode, according to the write-up [3]. Outside debug mode, an agent's call is stopped by the typed deserialization in each controller [3][5]. The post's claims for that step need a close read. It says Pydantic validators turn away invented JSON keys before they reach the database [4], but its code sample uses msgspec [7]. That struct sets no option for keys outside its two fields, so the snippet does not show whether a third key is refused or dropped. The string-for-boolean case depends on one word. The post says *strict* typing catches a string "true" at deserialization [5].
The speed figures are claims about someone else's workload. Besides the PydanticFastSerializer ratios, the release lists BodyMsgspec as 1.6x faster than the standard Body component [9]. The post's worked case assumes 200 ms of serialization overhead on each of 15 tool calls, or 3 extra seconds per workflow [10]. Suppose all 200 ms were deserialization and the 2.2x ratio held. Each call would still carry about 91 ms, which comes to about 1.4 seconds across the workflow [1]. For any of these multipliers to carry over, a team's payloads and baseline serializer would have to resemble whatever produced them.
The project's own tooling can test the boundary. Before letting agents call an endpoint that writes, I would run the post's three failure cases through the Schemathesis tests against a team's own models [15].
What to watch
- Project documentation stating, for each of the Pydantic, msgspec and attrs serializers, whether an unknown request key is rejected or ignored by default.
- Published methodology, including payload shapes, baseline and hardware, for the 2.2x, 1.33x, 1.6x and 65x figures.
- Any option to run the OpenAPI request check outside debug mode.