← Kursa Dön
📄 Text · 15 min

@PathVariable ve @RequestParam

REST API'lerde istemci tarafından gönderilen veriler farklı yollarla controller'a ulaştırılır. En yaygın iki mekanizma Path Variable (URL yolu içindeki değişkenler) ve Request Parameter (query string parametreleri) dir. Bu iki kavramı iyi anlamak, temiz ve RESTful API tasarımı için kritiktir.

URL Anatomisi

Önce bir URL'in bileşenlerini anlayalım:

https://api.example.com/users/42/orders?status=active&page=1
│       │                  │    │  │      │              │
│       │                  │    │  │      │              └─ Query Parameter
│       │                  │    │  │      └─ Query Parameter
│       │                  │    │  └─ Path Segment
│       │                  │    └─ Path Variable (42)
│       │                  └─ Path Segment
│       └─ Host
└─ Protocol

Genel kural: Kaynağı tanımlayan bilgiler path'te, filtreleme/sayfalama bilgileri query parameter'da olmalıdır.

@PathVariable — URL Yolu Değişkenleri

@PathVariable, URL yolu içindeki dinamik segmentleri Java metot parametrelerine bağlar. RESTful URL tasarımında kaynakları tanımlamak için kullanılır.

@RestController
@RequestMapping("/api")
public class UserController {

    // GET /api/users/42
    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }

    // GET /api/users/42/orders/7
    @GetMapping("/users/{userId}/orders/{orderId}")
    public Order getUserOrder(@PathVariable Long userId,
                               @PathVariable Long orderId) {
        return orderService.findByUserAndId(userId, orderId);
    }

    // Değişken adı farklıysa name ile belirtin
    @GetMapping("/departments/{dept-id}/employees/{emp-id}")
    public Employee getEmployee(
            @PathVariable("dept-id") Long departmentId,
            @PathVariable("emp-id") Long employeeId) {
        return employeeService.find(departmentId, employeeId);
    }
}

@PathVariable Özellikleri:

  • name / value: URL template'teki değişken adı. Parametre adı aynıysa belirtmeye gerek yok.

  • required: Varsayılan true. false yapılabilir ama dikkatli kullanılmalı.

// Optional PathVariable — URI pattern'de dikkat gerekir
@GetMapping({"/books", "/books/{isbn}"})
public Object getBooks(@PathVariable(required = false) String isbn) {
    if (isbn == null) {
        return bookService.findAll();
    }
    return bookService.findByIsbn(isbn);
}

@RequestParam — Query String Parametreleri

@RequestParam, URL'deki query string parametrelerini (?key=value) Java metot parametrelerine bağlar. Filtreleme, sıralama, arama ve sayfalama gibi işlemler için idealdir.

@RestController
@RequestMapping("/api/products")
public class ProductController {

    // GET /api/products?category=electronics&minPrice=100&maxPrice=500
    @GetMapping
    public List<Product> searchProducts(
            @RequestParam(required = false) String category,
            @RequestParam(defaultValue = "0") double minPrice,
            @RequestParam(defaultValue = "999999") double maxPrice) {
        return productService.search(category, minPrice, maxPrice);
    }

    // GET /api/products/search?q=laptop&page=0&size=20&sort=price,asc
    @GetMapping("/search")
    public Page<Product> search(
            @RequestParam String q,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size,
            @RequestParam(defaultValue = "name,asc") String sort) {
        return productService.search(q, PageRequest.of(page, size));
    }
}

@RequestParam Özellikleri:

ÖzellikAçıklamaVarsayılan
name / valueParametre adıMetot parametre adı
requiredZorunlu mu?true
defaultValueYoksa kullanılacak değerYok
// required = false → parametre gönderilmezse null olur
@GetMapping("/users")
public List<User> getUsers(
        @RequestParam(required = false) String name,
        @RequestParam(defaultValue = "1") int page,
        @RequestParam(defaultValue = "10") int size) {
    // name null olabilir, page varsayılan 1, size varsayılan 10
    return userService.findUsers(name, page, size);
}

Dikkat: defaultValue belirtildiğinde, required otomatik olarak false gibi davranır — parametre gönderilmezse default değer kullanılır.

@PathVariable vs @RequestParam — Ne Zaman Hangisi?

Bu iki annotation'ı doğru yerde kullanmak, temiz RESTful API tasarımının temelidir:

Kullanım Amacı@PathVariable@RequestParam
Kaynak tanımlama/users/42
Filtreleme?status=active
Sıralama?sort=name,asc
Sayfalama?page=0&size=20
Arama?q=spring+boot
Alt kaynak erişimi/users/42/orders
Zorunlu mu?Genellikle evetGenellikle hayır

Doğru örnekler:

GET /api/users/42              → @PathVariable (kaynak tanımlama)
GET /api/users?role=admin      → @RequestParam (filtreleme)
GET /api/users/42/orders       → @PathVariable (alt kaynak)
GET /api/orders?status=pending → @RequestParam (filtreleme)
DELETE /api/users/42           → @PathVariable (kaynak tanımlama)

Yanlış örnekler:

GET /api/users?id=42           → ❌ Kaynak id PathVariable olmalı
GET /api/users/role/admin      → ❌ Filtreleme RequestParam olmalı

Çoklu Parametre Alma — Map ile

Parametre sayısı çok olduğunda veya dinamik olduğunda Map kullanabilirsiniz:

// Tüm query parametrelerini Map olarak al
@GetMapping("/search")
public List<Product> search(@RequestParam Map<String, String> params) {
    String query = params.get("q");
    String category = params.getOrDefault("category", "all");
    int page = Integer.parseInt(params.getOrDefault("page", "0"));
    return productService.search(query, category, page);
}

// Tüm path variable'ları Map olarak al
@GetMapping("/locations/{country}/{city}")
public Location getLocation(@PathVariable Map<String, String> pathVars) {
    String country = pathVars.get("country");
    String city = pathVars.get("city");
    return locationService.find(country, city);
}

@MatrixVariable — Matris Parametreleri

Matris değişkenleri, URL path segment'leri içinde noktalı virgülle ayrılmış parametrelerdir. Nadir kullanılır ama belirli senaryolarda kullanışlıdır:

GET /api/cars/color=red;year=2024/brand=toyota
// MatrixVariable kullanmak için yapılandırma gerekir
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setRemoveSemicolonContent(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }
}

@GetMapping("/cars/{specs}")
public List<Car> getCars(
        @MatrixVariable(pathVar = "specs") Map<String, String> specs) {
    // specs = {color=red, year=2024}
    return carService.search(specs);
}

URI Template Variables — Gelişmiş Kullanım

// Birden fazla path variable ile karmaşık URL'ler
@GetMapping("/api/v{version}/tenants/{tenantId}/users/{userId}")
public User getUser(@PathVariable int version,
                     @PathVariable String tenantId,
                     @PathVariable Long userId) {
    // Multi-tenant API tasarımı
    return userService.findByTenant(tenantId, userId);
}

// Optional ile nullable PathVariable (Java 8+)
@GetMapping("/categories/{id}")
public ResponseEntity<Category> getCategory(@PathVariable Long id) {
    return categoryService.findById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
}

Tip Dönüşümü ve Hata Yönetimi

Spring, path variable ve request parameter değerlerini otomatik olarak hedef tipe dönüştürür. Eğer dönüşüm başarısız olursa 400 Bad Request yanıtı döner:

@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
    // /users/abc → 400 Bad Request (Long'a çevrilemez)
    // /users/42  → id = 42L
    return userService.findById(id);
}

// Enum otomatik dönüşümü
@GetMapping("/orders")
public List<Order> getOrders(@RequestParam OrderStatus status) {
    // ?status=PENDING → OrderStatus.PENDING
    // ?status=invalid → 400 Bad Request
    return orderService.findByStatus(status);
}

💡 Özet: Kaynak tanımlama için @PathVariable, filtreleme/sayfalama/arama için @RequestParam kullanın. required ve defaultValue özelliklerini uygun şekilde yapılandırın. RESTful URL tasarım kurallarına uyun.