Skip to main content

Ensure Optional REST Parameters Use Object Types

High
reliabilityerror-prevention

What is it?

This practice focuses on using object types for optional REST parameters to prevent runtime exceptions caused by null values being mapped to primitive types.

Why apply it?

By ensuring REST parameters use object types or are wrapped in Optional, you prevent runtime exceptions in Spring applications caused by the inability to map null values to primitive types, thereby ensuring more robust and error-free applications.

How to fix it?

Replace primitive types with their corresponding wrapper object types or use Optional<T>, ensuring a more graceful handling of absent parameters.

Examples

Example 1:

Negative

The negative example shows using a primitive type int for a REST parameter marked as optional, which can lead to a runtime exception.

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ArticleController {

@RequestMapping(value = {"/article", "/article/{id}"})
public String getArticle(@PathVariable(required = false) int articleId) { // Noncompliant
return "Article ID: " + articleId;
}
}

Example 2:

Positive

The positive example demonstrates using an object type Integer for a REST parameter, ensuring that a null value can be handled properly.

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ArticleController {

@RequestMapping(value = {"/article", "/article/{id}"})
public String getArticle(@PathVariable(required = false) Integer articleId) {
if (articleId != null) {
return "Article ID: " + articleId;
} else {
return "No Article ID provided";
}
}
}

Negative

This negative example again uses a primitive type int for a REST parameter with required = false, leading to potential issues.

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ArticleController {

@RequestMapping(value = {"/article", "/article/{id}"})
public String getArticle(@PathVariable(required = false) int articleId) { // Noncompliant
return "Article ID: " + articleId;
}
}

Example 3:

Positive

This positive example uses Optional<Integer> for the parameter, which is a recommended practice in handling optional REST parameters gracefully.

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Optional;

@RestController
public class ArticleController {

@RequestMapping(value = {"/article", "/article/{id}"})
public String getArticle(@PathVariable Optional<Integer> articleId) {
return articleId.map(id -> "Article ID: " + id)
.orElse("No Article ID provided");
}
}