Guide
A useful mental model for how all the topics connect:
URI
↓
HttpClient
↓
HTTP Request
↓
REST API
↓
HTTP Response
↓
JSON
↓
Jackson / ObjectMapper
↓
DTO
↓
Java application
- What information does a URI give us?
- What might
/usersand/42represent? - Why might
/users/42be preferable to/getUser?id=42in a REST API?
URI stands for Uniform Resource Identifier. It is a string used to identify a resource.
Example:
https://api.example.com/users/42
Here:
usersrepresents a type or collection of resources.42identifies one particular user.
REST APIs normally focus URIs on resources, while the HTTP method describes the action.
GET /users/42
DELETE /users/42
Both refer to the same resource, but perform different actions.
URL stands for Uniform Resource Locator. It is a type of URI that also tells us how to access the resource (e.g., using HTTP).
- Why is JSON commonly used by APIs?
- What types of values can JSON contain?
- How would you represent a person, address, and hobbies in JSON?
JSON stands for JavaScript Object Notation. It is a text format used to exchange structured data between systems.
{
"name": "Anna",
"age": 25,
"student": true
}
JSON supports:
- Strings
- Numbers
- Booleans
- Objects
- Arrays
null
Example of a more complex structure:
{
"name": "Anna",
"age": 25,
"active": true,
"address": {
"city": "Copenhagen"
},
"hobbies": ["Gaming", "Running"],
"nickname": null
}
JSON is popular because it is relatively compact, human-readable, and supported by almost every modern programming language.
- What is the difference between a simple value and a data structure?
- When would we use a
List, array,Map, or object? - What makes a data structure complex?
A data structure is a way of organizing data so a program can work with it effectively.
Examples in Java:
List<String> names;
Map<String, Integer> scores;
String[] products;
Objects can also represent structured data:
class Person {
String name;
int age;
}
A complex structure can contain other structures:
class Person {
String name;
Address address;
List<String> hobbies;
}
- Why not just work directly with a JSON string?
- What advantages does a DTO give us?
- Should DTOs contain business logic?
DTO stands for Data Transfer Object. It is an object primarily designed to carry data between different parts of a system.
public class UserDTO {
private String name;
private int age;
}
Instead of manually extracting information from JSON, we can work with normal Java objects:
user.getName();
DTOs give us Java types, IDE support, and compiler checking.
A DTO should generally focus on representing and transferring data, rather than containing lots of business logic.
- How could this JSON be represented as a Java DTO?
- What happens if the JSON and Java property names are different?
- What happens if the API adds another property?
{
"name": "Anna",
"age": 25
}
public class UserDTO {
private String name;
private int age;
// getters and setters
}
Jackson can convert between these representations.
JSON
↓
Jackson
↓
UserDTO
If the JSON uses a different property name, Jackson can be configured to map it:
@JsonProperty("first_name")
private String firstName;
Depending on the Jackson configuration, unknown JSON properties may either be ignored or cause an error.
- What makes an API RESTful?
- What is a resource?
- What is the difference between
/usersand/users/42? - What do the common HTTP methods mean?
A REST API is an API designed around resources and standard HTTP concepts.
Examples of resources:
/users
/users/42
/products
/products/15
Common HTTP methods:
| Method | Typical purpose |
|---|---|
GET | Retrieve data |
POST | Create something |
PUT | Replace/update something |
PATCH | Partially update something |
DELETE | Delete something |
For example:
GET /users/42
means approximately: Give me user 42.
DELETE /users/42
means approximately: Delete user 42.
- How do we know whether an API request succeeded?
- Does receiving a response mean the request was successful?
- What should our program do with a
404or500?
HTTP status codes describe the result of an HTTP request.
| Code | Typical meaning |
|---|---|
200 | OK |
201 | Created |
400 | Bad Request |
401 | Unauthorized |
403 | Forbidden |
404 | Not Found |
500 | Internal Server Error |
For example:
GET /users/999999
might return:
404 Not Found
Receiving an HTTP response does not necessarily mean that the operation succeeded. A 404 is still a valid HTTP response.
- What happens when our Java application calls an API?
- Where does JSON appear in the process?
- Who creates the JSON: our Java application or the server?
The basic process is:
Java application
↓
HTTP request
↓
REST API
↓
HTTP response
↓
JSON
Our application could request:
GET https://api.example.com/users/42
The server could respond with:
{
"id": 42,
"name": "Anna"
}
Our application can then process the response.
- What problems can happen before we receive JSON?
- What problems can happen after we receive JSON?
- Which problems are HTTP problems and which are conversion problems?
Network and HTTP problems include:
No internet connection
Server unavailable
Wrong URI
404 response
401 response
500 response
Timeout
JSON/data problems include:
Invalid JSON
Unexpected JSON structure
Wrong data type
Missing required property
DTO does not match JSON
Successfully contacting an API does not guarantee that we can successfully process its response.
- What is
HttpClientresponsible for? - Does
HttpClientunderstand JSON? - What is the difference between fetching and converting data?
HttpClient is a Java class for sending HTTP requests and receiving HTTP responses.
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/users/42"))
.GET()
.build();
HttpResponse<String> response =
client.send(request, HttpResponse.BodyHandlers.ofString());
The response body might contain JSON:
{
"id": 42,
"name": "Anna"
}
HttpClient handles HTTP communication. It does not automatically turn that JSON into our DTO.
A useful separation of responsibilities is:
HttpClient → HTTP communication
Jackson → JSON conversion
DTO → Java representation of the data
- Why shouldn’t we immediately convert every response body into a DTO?
- What might the response body contain when the status is
404or500?
Before processing a response as our expected data, we should check whether the request succeeded.
if (response.statusCode() == 200) {
// Process JSON
} else {
// Handle error
}
For example, a 404 response might contain error JSON instead of user JSON.
- Why use Jackson instead of manually parsing JSON strings?
- What does serialization mean?
- What does deserialization mean?
Jackson is a popular Java library for working with JSON.
It can convert:
JSON → Java object
Java object → JSON
These operations have names:
JSON → Java = deserialization
Java → JSON = serialization
Jackson saves us from manually finding and converting every value inside a JSON string.
- What does
ObjectMapperdo? - How does it know which JSON properties belong to which Java fields?
- What could cause the conversion to fail?
ObjectMapper is one of Jackson’s main classes for converting between JSON and Java objects.
ObjectMapper mapper = new ObjectMapper();
UserDTO user = mapper.readValue(json, UserDTO.class);
Conceptually:
JSON string
↓
ObjectMapper
↓
UserDTO
Jackson examines the JSON properties and the structure of the Java class and attempts to map corresponding values.
- Why might we need to convert Java objects into JSON?
- Which type of HTTP request might send JSON to an API?
Jackson can also convert a Java object into JSON.
UserDTO user = new UserDTO();
user.setName("Anna");
user.setAge(25);
String json = mapper.writeValueAsString(user);
This could produce:
{
"name": "Anna",
"age": 25
}
A useful memory aid is:
readValue()
JSON → Java
writeValueAsString()
Java → JSON
This is especially useful when sending data with requests such as POST, PUT, or PATCH.
How many DTO classes would you create for this JSON, and why?
{
"id": 123,
"customer": {
"name": "Anna",
"email": "anna@example.com"
},
"items": [
{
"name": "Keyboard",
"quantity": 1
},
{
"name": "Mouse",
"quantity": 2
}
]
}
We could create three DTO classes:
class OrderDTO {
int id;
CustomerDTO customer;
List<OrderItemDTO> items;
}
class CustomerDTO {
String name;
String email;
}
class OrderItemDTO {
String name;
int quantity;
}
The structure then looks like:
OrderDTO
├── id
├── CustomerDTO
│ ├── name
│ └── email
└── List<OrderItemDTO>
├── item
└── item
Understanding the JSON structure first makes designing DTOs much easier.
Imagine that we want information about user 42.
https://api.example.com/users/42
The URI identifies the resource we want.
Java sends an HTTP request:
GET /users/42
The server receives the request and finds the requested resource.
The server responds with something like:
{
"id": 42,
"name": "Anna",
"age": 25
}
We convert the JSON into a Java object:
UserDTO user = mapper.readValue(json, UserDTO.class);
Now we can use normal Java code:
user.getName();
Result:
Anna
When I write Java code that displays the name of a user, Pokémon, movie, or product fetched from an external API, what exactly happens between pressing Run and seeing the name printed?
Explain the complete chain in your own words:
URI
↓
HttpClient
↓
HTTP Request
↓
REST API
↓
HTTP Response
↓
JSON
↓
ObjectMapper / Jackson
↓
DTO
↓
Java code