Appearance
Request and Response Formats
This document provides a detailed specification for the JSON request and response formats used in the IT Ticketing Service API. These data structures serve as the primary contract between API clients and the service.
The application follows the Data Transfer Object (DTO) pattern, separating the API representation from the internal persistence model (Ticket.java). This approach provides several benefits:
- API Stability: The API contract (
TicketRequest,TicketResponse) can evolve independently of the underlying database schema. - Security: It prevents accidental exposure of sensitive or internal entity fields.
- Flexibility: It allows for tailored request and response payloads, optimizing for different use cases (e.g., a creation request doesn't need an
idorcreatedAttimestamp).
For a complete reference of the endpoints that use these formats, see the Ticket Endpoints API Reference.
TicketRequest Schema
The TicketRequest DTO is used as the payload for creating a new ticket (POST /api/tickets) and updating an existing one (PUT /api/tickets/{id}). It contains all the user-provided fields necessary to define a ticket.
java
// src/main/java/com/slalom/demo/ticketing/dto/TicketRequest.java
package com.slalom.demo.ticketing.dto;
import com.slalom.demo.ticketing.model.TicketPriority;
import com.slalom.demo.ticketing.model.TicketStatus;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class TicketRequest {
@NotBlank(message = "Title is required")
private String title;
@NotBlank(message = "Description is required")
private String description;
@NotNull(message = "Status is required")
private TicketStatus status;
@NotNull(message = "Priority is required")
private TicketPriority priority;
@NotBlank(message = "Requester email is required")
@Email(message = "Invalid email format")
private String requesterEmail;
private String assignedTo;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Field Definitions
| Field | Type | Required | Description |
|---|---|---|---|
title | String | Yes | A brief, descriptive title for the ticket. |
description | String | Yes | A detailed description of the issue or request. |
status | String (Enum) | Yes | The current status of the ticket. |
priority | String (Enum) | Yes | The urgency or priority level of the ticket. |
requesterEmail | String | Yes | The email address of the person who created the ticket. |
assignedTo | String | No | The email address of the person assigned to resolve the ticket. Can be null. |
Example Payload
Below is an example of a valid JSON payload for creating a new ticket.
json
{
"title": "Network connectivity issue in Building C",
"description": "Users on the third floor of Building C are reporting intermittent loss of Wi-Fi connectivity. The issue started around 10:00 AM.",
"status": "OPEN",
"priority": "HIGH",
"requesterEmail": "network.admin@example.com",
"assignedTo": "jane.doe@example.com"
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
TicketResponse Schema
The TicketResponse DTO is the standard format for all responses that return ticket data, including GET /api/tickets/{id} and list operations. It includes all fields from the request, plus server-generated fields like the unique identifier and timestamps.
java
// src/main/java/com/slalom/demo/ticketing/dto/TicketResponse.java
package com.slalom.demo.ticketing.dto;
import com.slalom.demo.ticketing.model.TicketPriority;
import com.slalom.demo.ticketing.model.TicketStatus;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class TicketResponse {
private Long id;
private String title;
private String description;
private TicketStatus status;
private TicketPriority priority;
private String requesterEmail;
private String assignedTo;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
private LocalDateTime resolvedAt;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Response Field Mapping
| Field | Type | Source |
|---|---|---|
id | Long | Auto-generated primary key from the database (@Id, @GeneratedValue). |
title | String | User-provided. |
description | String | User-provided. |
status | String (Enum) | User-provided. |
priority | String (Enum) | User-provided. |
requesterEmail | String | User-provided. |
assignedTo | String | User-provided. |
createdAt | LocalDateTime | Auto-generated by JPA/Hibernate (@CreationTimestamp) on entity creation. |
updatedAt | LocalDateTime | Auto-generated by JPA/Hibernate (@UpdateTimestamp) on entity creation and subsequent updates. |
resolvedAt | LocalDateTime | Set by application logic when the ticket status changes to RESOLVED. null otherwise. |
Example Response
Below is an example of a JSON response for a ticket that has been created and is in progress.
json
{
"id": 101,
"title": "Network connectivity issue in Building C",
"description": "Users on the third floor of Building C are reporting intermittent loss of Wi-Fi connectivity. The issue started around 10:00 AM.",
"status": "IN_PROGRESS",
"priority": "HIGH",
"requesterEmail": "network.admin@example.com",
"assignedTo": "jane.doe@example.com",
"createdAt": "2024-10-27T10:05:15.123456",
"updatedAt": "2024-10-27T11:30:00.789012",
"resolvedAt": null
}1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
Field Descriptions
This section provides detailed descriptions of each field and its purpose within the ticketing system. For details on how these fields map to the database, refer to the Data Model documentation.
| Field | Description |
|---|---|
title | A concise summary of the ticket. This is often used in list views and notifications. |
description | A comprehensive, multi-line description of the problem or request. It should contain all relevant details for the assignee to begin work. The database column supports up to 2000 characters. |
status | The current stage of the ticket in its lifecycle. This is an enum with the following possible values: OPEN, IN_PROGRESS, WAITING_ON_CUSTOMER, RESOLVED, CLOSED. |
priority | The level of urgency assigned to the ticket, which helps in prioritizing work. This is an enum with the following possible values: LOW, MEDIUM, HIGH, CRITICAL. |
requesterEmail | The email address of the user or system that reported the issue. Used for contact and notifications. |
assignedTo | The email address of the support agent or team member responsible for handling the ticket. This field is optional and can be null if the ticket is unassigned. |
Validation Constraints
The application uses the spring-boot-starter-validation dependency to enforce constraints on incoming TicketRequest payloads. If a request violates any of these rules, the API will respond with a 400 Bad Request status and a message detailing the validation failures.
The constraints are defined using jakarta.validation.constraints annotations directly on the TicketRequest DTO.
| Field | Constraint(s) | Description |
|---|---|---|
title | @NotBlank | The field must not be null and must contain at least one non-whitespace character. An empty string ("") or a string with only spaces (" ") is invalid. |
description | @NotBlank, length = 2000 (DB level) | Must not be blank. While not enforced at the DTO level, the underlying database column has a VARCHAR(2000) limit. Payloads exceeding this may cause a DataIntegrityViolationException. |
status | @NotNull | The field must not be null. The value must be one of the valid TicketStatus enum constants. |
priority | @NotNull | The field must not be null. The value must be one of the valid TicketPriority enum constants. |
requesterEmail | @NotBlank, @Email | Must not be blank and must conform to a standard email address format (e.g., user@domain.com). The validation is handled by Hibernate Validator's default email pattern. |
assignedTo | (None) | This field is optional and can be null or an empty string. No validation is applied. |
Gotchas and Edge Cases
@NotBlankvs.@NotNull: Note the distinction.statusandpriorityuse@NotNullbecause they are enums and cannot be "blank" in the string sense.title,description, andrequesterEmailuse@NotBlankto prevent users from submitting empty or whitespace-only strings.- Enum Case Sensitivity: The default Spring Boot configuration for deserializing enums is case-sensitive. A request with
status: "open"will fail validation; it must bestatus: "OPEN". - Description Length: The
descriptionfield's length is only constrained at the database level. A robust client should ideally enforce a 2000-character limit to prevent API errors. Future work could involve adding a@Size(max=2000)annotation to the DTO for early validation.