Request body and DTOs
To create a post, a client sends a POST request with JSON in the request body. Spring can turn that JSON into a Java object. Input data usually gets its own class — a DTO (data transfer object). It holds only the fields the client is allowed to send.
A record for input data
// src/main/java/com/example/blog/NewPostRequest.java
package com.example.blog;
public record NewPostRequest(String title, String body, String author) {
}There is no id or creation date here: the server assigns them, not the client. If we accepted Post directly, a client could send its own id and overwrite someone else's post.
The controller method
// src/main/java/com/example/blog/PostController.java
@PostMapping
public Post create(@RequestBody NewPostRequest request) {
return postService.create(request);
}@RequestBody tells Spring: read the request body as JSON and build a NewPostRequest from it. JSON field names must match the record component names.
The service method
// src/main/java/com/example/blog/PostService.java
public Post create(NewPostRequest request) {
Post post = new Post(null, request.title(), request.body(), request.author(), Instant.now(clock));
return repository.save(post);
}The service adds what the request lacks: the creation time. The store assigns the id when saving.
Sending a request
curl -X POST http://localhost:8080/api/posts \
-H "Content-Type: application/json" \
-d '{"title":"Hello, Spring","body":"First post","author":"anna"}'{"id":1,"title":"Hello, Spring","body":"First post","author":"anna","createdAt":"2026-10-04T08:50:07.494425300Z"}-X POST sets the method, -H a header, -d the request body. The response is the saved post, now with an id and a date. curl http://localhost:8080/api/posts will show it in the list.
The curl examples in this course are written for bash. On Windows run them in Git Bash or WSL: in cmd and PowerShell single quotes around JSON behave differently. Also, on Windows non-English letters in curl arguments may be sent in a legacy code page, and the server answers 400 with Invalid UTF-8 middle byte in the log. In that case save the JSON to a UTF-8 file and send it like this: curl ... -d @post.json.
Extra and missing fields
| Situation | What Spring does |
|---|---|
| JSON has a field the record lacks | Ignores it |
| JSON lacks a field of the record | Sets null |
| JSON is broken, for example a missing closing brace | Answers 400 Bad Request |
To keep null values out of the store, the data has to be checked — that is the topic of the validation lesson.
Common mistake
If you forget the Content-Type: application/json header, curl sends the data as a form, and Spring refuses to read it:
HTTP/1.1 415
Accept: application/json, application/*+json
{"timestamp":"2026-10-04T08:50:07.998Z","status":415,"error":"Unsupported Media Type","path":"/api/posts"}Code 415 means "unsupported media type". The Accept header in the response hints at the type the server expects.