Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. Spring Dictionary
  3. @PathVariable

@PathVariable

Since: Spring Boot 3(2022)

@PathVariable in Spring binds a portion of the URL path to a controller method argument. You write {variableName} in a path template such as @GetMapping("/{id}"), then annotate the corresponding method parameter with @PathVariable. Spring automatically converts the value found in the URL to the declared parameter type. This is commonly used in REST APIs to include a resource identifier — such as an ID or slug — directly in the URL.

Syntax

// Write {variableName} in the URL path template
@GetMapping("/path/{variableName}")
public ReturnType methodName(@PathVariable Type variableName) {
    return responseData;
}

// If the parameter name differs from the template variable name, specify it with the value attribute
@GetMapping("/path/{id}")
public ReturnType methodName(@PathVariable("id") Long userId) {
    return responseData;
}

// You can also receive multiple path variables at the same time
@GetMapping("/categories/{categoryId}/items/{itemId}")
public ReturnType methodName(
        @PathVariable Long categoryId,
        @PathVariable Long itemId) {
    return responseData;
}

Attributes

AttributeDescription
value / nameSpecifies the name of the path template variable to bind, as a string. You can omit this attribute when the method parameter name matches the template variable name.
requiredSpecifies whether the path variable is required, as a boolean. The default is true. When set to false, the method also matches paths where the variable is absent, and the parameter receives null or an Optional.

Sample Code

An example REST API that retrieves, updates, and deletes a user resource by ID.

package com.example.demo;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

// Register this class as a REST controller with @RestController
// Set the base path to /api/users with @RequestMapping
@RestController
@RequestMapping("/api/users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    // Handles GET /api/users/{id}
    // The {id} value in the URL path is converted to Long and passed to the id parameter
    @GetMapping("/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        if (user == null) {
            // Return 404 if no matching user is found
            return ResponseEntity.notFound().build();
        }
        // Return 200 with the user data if found
        return ResponseEntity.ok(user);
    }

    // Handles PUT /api/users/{id}
    // Receives the request body with @RequestBody and updates the user identified by id
    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(
            @PathVariable Long id,
            @RequestBody UserRequest request) {
        User updated = userService.update(id, request);
        return ResponseEntity.ok(updated);
    }

    // Handles DELETE /api/users/{id}
    // Returns 204 with no body on successful deletion
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.delete(id);
        return ResponseEntity.noContent().build();
    }
}

An example that combines multiple path variables to represent nested resources, such as categories and items.

package com.example.demo;

import java.util.List;

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

@RestController
@RequestMapping("/api/categories")
public class ItemController {

    private final ItemService itemService;

    public ItemController(ItemService itemService) {
        this.itemService = itemService;
    }

    // GET /api/categories/{categoryId}/items retrieves all items in the specified category
    // {categoryId} is converted to Long and passed to the categoryId parameter
    @GetMapping("/{categoryId}/items")
    public List<Item> getItems(@PathVariable Long categoryId) {
        return itemService.findByCategoryId(categoryId);
    }

    // GET /api/categories/{categoryId}/items/{itemId} retrieves details of a specific item
    // Each of the two path variables is received by a separate parameter
    @GetMapping("/{categoryId}/items/{itemId}")
    public Item getItem(
            @PathVariable Long categoryId,
            @PathVariable Long itemId) {
        return itemService.findByCategoryIdAndItemId(categoryId, itemId);
    }
}

An example that uses required = false to define an optional path variable. This is useful in versioned APIs and similar scenarios.

package com.example.demo;

import java.util.Optional;

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

@RestController
@RequestMapping("/api/reports")
public class ReportController {

    private final ReportService reportService;

    public ReportController(ReportService reportService) {
        this.reportService = reportService;
    }

    // Handles both GET /api/reports and GET /api/reports/{year} with a single method
    // Setting required = false routes both paths to this method even when the variable is omitted
    // Using Optional<Integer> allows safe null checking
    @GetMapping({"", "/{year}"})
    public String getReport(@PathVariable(required = false) Optional<Integer> year) {
        if (year.isPresent()) {
            // Return the report for the specified year
            return reportService.getByYear(year.get());
        }
        // Return the latest report when the year is omitted
        return reportService.getLatest();
    }
}

How It Works

@PathVariable is Spring MVC's mechanism for automatically converting URL path template variables into method arguments. Many types are supported, including String, int, Long, and UUID. If conversion fails — for example, when a string is passed to a path that expects a number — Spring automatically returns a 400 Bad Request response.

When the method parameter name matches the path template variable name, you can omit the value attribute of @PathVariable. However, if the Java compiler option -parameters is not enabled (as in some older build configurations), parameter names may be lost at compile time. In that case, writing @PathVariable("id") explicitly is more reliable. Spring Boot 3 and later enable -parameters by default, so the shorthand form is safe to use.

To receive query strings (?key=value), use @RequestParam instead of a path variable. In common REST design practice, path variables are used for values that uniquely identify a resource (such as IDs or slugs), while query parameters are used for supplementary options like filtering or sorting.

For defining GET endpoints, see @GetMapping. For PUT endpoints, see @PutMapping. For DELETE endpoints, see @DeleteMapping.

If you find any errors or copyright issues, please .