<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hai Nguyen</title>
    <description>The latest articles on DEV Community by Hai Nguyen (@haind3004).</description>
    <link>https://dev.to/haind3004</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3667083%2F16000732-1068-47d6-9991-021a5efb841a.png</url>
      <title>DEV Community: Hai Nguyen</title>
      <link>https://dev.to/haind3004</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/haind3004"/>
    <language>en</language>
    <item>
      <title>RESTful API: Why Is It Still the Standard for Web APIs?</title>
      <dc:creator>Hai Nguyen</dc:creator>
      <pubDate>Sat, 21 Mar 2026 09:54:14 +0000</pubDate>
      <link>https://dev.to/haind3004/restful-api-why-is-it-still-the-standard-for-web-apis-kk4</link>
      <guid>https://dev.to/haind3004/restful-api-why-is-it-still-the-standard-for-web-apis-kk4</guid>
      <description>&lt;p&gt;Imagine walking into a fine restaurant. You raise your hand, and a waiter comes to take your order along with your table number. The waiter delivers the request to the kitchen, and a few minutes later returns with the dish you asked for.&lt;/p&gt;

&lt;p&gt;You don’t need to know how the kitchen works, you only care that your order arrives correctly. Meanwhile, many other waiters are serving many other tables at the same time.&lt;/p&gt;

&lt;p&gt;If this sounds familiar, it’s because this is a common analogy used to explain how APIs work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxsfpo9xmqrikhwrpdvc8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxsfpo9xmqrikhwrpdvc8.png" alt="REST work as restaurant waiter" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the world of software, an API acts much like the waiter in this story. The client sends a request describing what it needs, the server processes that request, and then returns the result. The client does not need to understand the internal implementation of the server, only how to communicate with it.&lt;/p&gt;

&lt;p&gt;One of the most widely used approaches for building web APIs today is the REST architecture style. REST leverages the widely adopted HTTP protocol to standardize how clients request resources and how servers respond, typically using lightweight data formats such as JSON.&lt;/p&gt;

&lt;p&gt;Because of its simplicity, scalability, and compatibility with the web, RESTful APIs have become the de facto standard for modern web services.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is RESTful API ?
&lt;/h2&gt;

&lt;p&gt;Beginners often confuse REST with RESTful APIs due to how people casually use the term “REST API.”&lt;/p&gt;

&lt;h3&gt;
  
  
  To clarify:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;REST is a set of architectural principles&lt;/li&gt;
&lt;li&gt;RESTful API is an API that follows those REST principles
In short, a RESTful API is simply an API designed according to REST constraints.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;REST like a blueprint while RESTful Api is the iplementation&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Principle 1: Client–Server
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhhb08l2l1b5hv8qa5lvx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhhb08l2l1b5hv8qa5lvx.png" alt="Client server principal of rest api" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is the most fundamental principle.&lt;/strong&gt;&lt;br&gt;
Client and server are separated into independent entities. This allows one or multiple servers to serve one or many clients simultaneously.&lt;br&gt;
This separation decouples the user interface from the business logic, making it possible to update either side without affecting the other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easier to maintain&lt;/li&gt;
&lt;li&gt;Can scale independently&lt;/li&gt;
&lt;li&gt;Frontend and backend teams can work separately&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Principle 2: Stateless
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm1ivdnob9fmxd9im0bj0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm1ivdnob9fmxd9im0bj0.png" alt="Stateless principall of rest api" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The server does not store any previous request state.&lt;/strong&gt;&lt;br&gt;
Each request is independent and must contain all necessary information (e.g., authentication token, resource identifiers).&lt;br&gt;
This makes the system more scalable and reliable because any server can handle any request.&lt;/p&gt;

&lt;p&gt;Compare to stateful api, request depend on state of last request&lt;br&gt;
&lt;strong&gt;Server save state of client between requests&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example:&lt;/strong&gt;&lt;br&gt;
With stateless, after login request was sent to server with all informations like token, resource.. server don't need to remember last request, it just handle current request&lt;br&gt;
With stateful, after login, server need to create a session to save save your login session, if session was forget, you log out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefits&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eazy to scale&lt;/li&gt;
&lt;li&gt;Better performance&lt;/li&gt;
&lt;li&gt;Better for loadalancing
...&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Principle 3: Cacheable
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq07f3mdda7rkc8r8glqp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq07f3mdda7rkc8r8glqp.png" alt="Cacheable principal of rest api" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Server responses can be cached.&lt;br&gt;
REST allows clients (apps, browsers) or intermediaries (proxies) to store responses temporarily.&lt;br&gt;
Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce the number of requests to the server&lt;/li&gt;
&lt;li&gt;Improve response time&lt;/li&gt;
&lt;li&gt;Save bandwidth&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Principle 4: Uniform Interface
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7wl1sauymrunr2mvvcm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7wl1sauymrunr2mvvcm.png" alt="Uniform interface principal of rest api" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is the most important principle of REST.&lt;/strong&gt;&lt;br&gt;
It defines a consistent way to interact with resources.&lt;br&gt;
Each resource should have a unique URL:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get all users → /users&lt;/li&gt;
&lt;li&gt;Get a specific user → /users/1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avoid using action-based URLs like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;/getUser&lt;/li&gt;
&lt;li&gt;/createUser&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;REST leverages HTTP methods to define actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GET → retrieve data&lt;/li&gt;
&lt;li&gt;POST → create new data&lt;/li&gt;
&lt;li&gt;DELETE → remove data&lt;/li&gt;
&lt;li&gt;PUT → update entire resource&lt;/li&gt;
&lt;li&gt;PATCH → update partial resource&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Resource Representation&lt;/strong&gt;&lt;br&gt;
The server does not return raw objects or database records directly.&lt;br&gt;
Instead, it returns a representation of the resource, typically in formats like JSON or XML.&lt;br&gt;
For example, when building a RESTful API with Spring Framework, the backend does not expose Java objects directly—it returns JSON representations.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
  "id": "8f3c2a9e-5b1d-4c7a-9f2e-1a6b3d8c4e10",&lt;br&gt;
  "username": "john_doe92",&lt;br&gt;
  "email": "john.doe92@example.com",&lt;br&gt;
  "firstName": "John",&lt;br&gt;
  "lastName": "Doe",&lt;br&gt;
  "phone": "+1-202-555-0147",&lt;br&gt;
  "dateOfBirth": "1992-06-15",&lt;br&gt;
  "gender": "male"&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;This standardization allows different systems to communicate consistently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standardization comunication (commonly json/xml)&lt;/li&gt;
&lt;li&gt;Security (pass nessary information in request/response)&lt;/li&gt;
&lt;li&gt;api versioning&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Principle 5: Layered System
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4dbg47ez2j4ksnk4lf0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4dbg47ez2j4ksnk4lf0.png" alt="Layer system principal in restapi" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clients do not need to know whether they are communicating directly with the main server or through intermediaries.&lt;br&gt;
In modern architectures (especially microservices), requests often pass through multiple layers:&lt;/p&gt;

&lt;p&gt;For example: &lt;br&gt;
&lt;code&gt;Browser → CDN → Gateway → Load Balancer → Security → Business Service → Database&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;The client only needs to know the endpoint.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easier scaling&lt;/li&gt;
&lt;li&gt;Better maintainability&lt;/li&gt;
&lt;li&gt;Independent services&lt;/li&gt;
&lt;li&gt;Improved performance via load balancing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Principle 6: Code on Demand (Optional)
&lt;/h2&gt;

&lt;p&gt;Instead of sending only data (JSON/XML), the server can send executable code for the client to run.&lt;br&gt;
However, this approach is rarely used in modern APIs and is generally not recommended.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compare to other style of API
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;REST is a very good style of API, but not all time we use it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With out REST, there are many style of API like GraphQL, gPRC...&lt;br&gt;
Get gPRC for example, if you need a hign performance or realtime streaming&lt;br&gt;
Try to compare REST and gPRC&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu77yokj0axd6a3bn9ash.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu77yokj0axd6a3bn9ash.png" alt="REST vs gPRC" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;From a developer’s perspective, REST is not a protocol but a design philosophy.&lt;br&gt;
Understanding and applying these principles correctly will help you build APIs that are scalable, maintainable, and easy to use.&lt;br&gt;
A RESTful API is simply the practical implementation of those ideas.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>restapi</category>
      <category>api</category>
      <category>web</category>
    </item>
    <item>
      <title>Validating REST API Requests in Spring Boot in practice</title>
      <dc:creator>Hai Nguyen</dc:creator>
      <pubDate>Sun, 28 Dec 2025 10:53:18 +0000</pubDate>
      <link>https://dev.to/haind3004/validating-rest-api-requests-in-spring-boot-in-practice-2on8</link>
      <guid>https://dev.to/haind3004/validating-rest-api-requests-in-spring-boot-in-practice-2on8</guid>
      <description>&lt;h2&gt;
  
  
  Why validation belongs at the API boundary
&lt;/h2&gt;

&lt;p&gt;Imagine an API endpoint that accepts user input without any validation. One day, a client sends a request with a negative amount, an invalid email, and missing required fields. The request still reaches the service layer, corrupts business logic, and causes unexpected errors deep inside the system. The bug is hard to trace, not because the logic is complex, but because invalid data was never stopped at the boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens when a request arrives (overview)
&lt;/h2&gt;

&lt;p&gt;When a client sends an HTTP request to a Spring Boot application, a small pipeline runs before your controller code executes. Understanding that pipeline explains where validation belongs and when exceptions are thrown:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyvv9repg61srtu6cv11u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyvv9repg61srtu6cv11u.png" alt=" " width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;DispatcherServlet&lt;/code&gt; receives the request and resolves a controller handler.&lt;/li&gt;
&lt;li&gt;Spring prepares method invocation by resolving method arguments. For &lt;code&gt;@RequestBody&lt;/code&gt;, it uses an &lt;code&gt;HttpMessageConverter&lt;/code&gt; to deserialize JSON into the target DTO.&lt;/li&gt;
&lt;li&gt;During argument resolution, Spring integrates &lt;code&gt;Jakarta Bean Validation&lt;/code&gt; (Hibernate Validator by default). If a controller parameter is annotated with &lt;code&gt;@Valid&lt;/code&gt; or the controller is annotated with &lt;code&gt;@Validated&lt;/code&gt;, the deserialized DTO is validated automatically.
If any constraint violations are found, Spring raises a validation exception and does not invoke the controller method body.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The thrown exception is then routed through Spring's exception resolution mechanism, where application level handlers decide the HTTP response.&lt;/p&gt;
&lt;h2&gt;
  
  
  Common validation exceptions you should know
&lt;/h2&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;MethodArgumentNotValidException&lt;/code&gt;: Raised when validating an &lt;code&gt;@RequestBody&lt;/code&gt; fails (field-level or object-level violations). This exception carries the binding result with field errors and rejected values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ConstraintViolationException&lt;/code&gt;: Raised when method parameter validation (&lt;code&gt;@Validated&lt;/code&gt; on parameters, &lt;code&gt;@RequestParam&lt;/code&gt;, &lt;code&gt;@PathVariable&lt;/code&gt;, or programmatic validator calls) fails. The exception contains a set of &lt;code&gt;ConstraintViolations&lt;/code&gt; describing each failure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;HttpMessageNotReadableException&lt;/code&gt;: Raised when JSON parsing fails (malformed JSON) before validation even runs.&lt;br&gt;
These exceptions are thrown before your controller logic runs. The responsibility for shaping the HTTP response falls to the configured exception handlers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below are the simple code snippets that illustrate how validation is declared and enforced.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Request DTO (contract and annotations)

public class RequestPayload {
    @NotBlank
    private String name;

    @Email
    @NotBlank
    private String email;

    @NotBlank
    @DepartmentCodeValid
    private String departmentCode;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notes: the DTO declares both standard constraints (&lt;code&gt;@NotBlank&lt;/code&gt;, &lt;code&gt;@Email&lt;/code&gt;) and the custom domain constraint (&lt;code&gt;@DepartmentCodeValid&lt;/code&gt;) directly on the field. This keeps the data contract and validation rules colocated and self documenting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Custom constraint annotation

@Documented
@Constraint(validatedBy = DepartmentCodeValidator.class)
@Target({FIELD, PARAMETER})
@Retention(RUNTIME)
public @interface DepartmentCodeValid {
    String message() default "departmentCode must be one of 50..99";
    Class&amp;lt;?&amp;gt;[] groups() default {};
    Class&amp;lt;? extends Payload&amp;gt;[] payload() default {};
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Custom validator implementation
// this validator constrains that `departmentCode` must be in the 
// defined codes

public class DepartmentCodeValidator implements ConstraintValidator&amp;lt;DepartmentCodeValid, String&amp;gt; {
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null || value.isBlank()) {
            return false;
        }
        try {
            int code = Integer.parseInt(value);
            for (DepartmentCode dc : DepartmentCode.values()) {
                if (dc.getCode() == code) {
                    return true;
                }
            }
            return false;
        } catch (NumberFormatException e) {
            return false;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Domain enumeration of allowed department codes

public enum DepartmentCode {
    CODE_50(50),
    CODE_98(98),
    ...
    CODE_99(99);

    private final int code;

    DepartmentCode(int code) {
        this.code = code;
    }

    public int getCode() {
        return code;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Controller that accepts the request

@RestController
@RequestMapping("/api/requests")
public class RequestController {
    private final CacheService cacheService;

    public RequestController(CacheService cacheService) {
        this.cacheService = cacheService;
    }

    @PostMapping
    public ResponseEntity&amp;lt;RequestPayload&amp;gt; create(@Valid @RequestBody RequestPayload payload) {
        var saved = cacheService.save(payload);
        return ResponseEntity.ok(saved);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How validation failure is raised and routed (walkthrough)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When the POST handler receives a request, Spring deserializes the JSON body into &lt;code&gt;RequestPayload&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Because the create method parameter is annotated with &lt;code&gt;@Valid&lt;/code&gt;, the bean validation engine runs automatically.&lt;/li&gt;
&lt;li&gt;The engine executes built-in constraints (&lt;code&gt;@NotBlank&lt;/code&gt;, &lt;code&gt;@Email&lt;/code&gt;) and the custom &lt;code&gt;DepartmentCodeValidator&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If the custom validator rejects the &lt;code&gt;departmentCode&lt;/code&gt; (or any other constraint fails), the engine records violations and Spring throws &lt;code&gt;MethodArgumentNotValidException&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Spring's HandlerExceptionResolver chain (including any @RestControllerAdvice) receives that exception and decides how to convert it into an HTTP response. The controller method body is never invoked.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Centralizing validation error handling recommended
&lt;/h2&gt;

&lt;p&gt;Below is an illustrative &lt;code&gt;GlobalExceptionHandler&lt;/code&gt; you can adopt in the project. It is shown inline here to demonstrate how the binding errors and constraint violations can be transformed into a stable JSON error envelope.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity&amp;lt;ValidationErrorResponse&amp;gt; handleBindingErrors(MethodArgumentNotValidException ex,
                                                                       HttpServletRequest request) {
        List&amp;lt;FieldError&amp;gt; errors = ex.getBindingResult().getFieldErrors().stream()
            .map(fe -&amp;gt; new FieldError(fe.getField(), fe.getDefaultMessage(), fe.getRejectedValue()))
            .collect(Collectors.toList());

        ValidationErrorResponse body = new ValidationErrorResponse(
            OffsetDateTime.now(), HttpStatus.BAD_REQUEST.value(), request.getRequestURI(), errors
        );
        return ResponseEntity.badRequest().body(body);
    }

    // Example: handle type mismatches or malformed values for query/path params
    @ExceptionHandler({ MethodArgumentTypeMismatchException.class })
    public ResponseEntity&amp;lt;ValidationErrorResponse&amp;gt; handleTypeMismatch(MethodArgumentTypeMismatchException ex,
                                                                      HttpServletRequest request) {
        FieldError err = new FieldError(ex.getName(), "invalid value", ex.getValue());
        ValidationErrorResponse body = new ValidationErrorResponse(
            OffsetDateTime.now(), HttpStatus.BAD_REQUEST.value(), request.getRequestURI(), List.of(err)
        );
        return ResponseEntity.badRequest().body(body);
    }

    // Add other handlers (ConstraintViolationException, HttpMessageNotReadableException, etc.) as needed
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Minimal helper DTOs used above 
record FieldError(String field, String message, Object rejectedValue){}
record ValidationErrorResponse(OffsetDateTime timestamp, int status, String path, List&amp;lt;FieldError&amp;gt; errors) {}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;h4&gt;
  
  
  Notes on the example handle
&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;p&gt;The handler reads field errors from the binding result and maps them to a compact &lt;code&gt;FieldError&lt;/code&gt; structure. This is the most direct way to surface which property failed and why.&lt;br&gt;
The same pattern can be applied to &lt;code&gt;ConstraintViolationException&lt;/code&gt; by mapping each &lt;code&gt;ConstraintViolation&lt;/code&gt; to a field/property path.&lt;br&gt;
A consistent error envelope returned by the global handler might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "timestamp": "2025-12-28T12:34:56Z",
  "status": 400,
  "path": "/api/requests",
  "errors": [
    {
      "field": "departmentCode",
      "message": "departmentCode must be one of 50..99",
      "rejectedValue": "42"
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How Spring chooses which handler runs (internals, simplified)
&lt;/h2&gt;

&lt;p&gt;When the validation exception is thrown, Spring consults &lt;code&gt;HandlerExceptionResolvers&lt;/code&gt;. &lt;code&gt;@RestControllerAdvice&lt;/code&gt; backed &lt;code&gt;ExceptionHandlerExceptionResolver&lt;/code&gt; is consulted and, if a matching &lt;code&gt;@ExceptionHandler&lt;/code&gt; exists, delegates to it. The handler returns a value or &lt;code&gt;ResponseEntity&lt;/code&gt;, which Spring serializes to the HTTP response and ends processing.&lt;br&gt;
If no handler is present, Spring's fallback resolvers generate a default 400 response with a framework defined body.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Walk through the article, we can see that validation is the first line of defense for any service. It protects business logic and persistence from malformed or malicious input, improves client experience with clear errors, and reduces debugging time for both providers and consumers. Placing validation at the boundary just after HTTP mapping but before controller logic lets you fail fast and keep deeper layers simple.&lt;/p&gt;

&lt;p&gt;Hopefully the artical can help you to more get more understand about the validation workflow and helpful for developer career, thanks youuu... ☺️&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>java</category>
      <category>springboot</category>
      <category>api</category>
    </item>
  </channel>
</rss>
