පැති Variable සහ Request Param: ඔබගේ REST API බලවත් කරමු! (Path Variables & Request Params SC Guide)

පැති Variable සහ Request Param: ඔබගේ REST API බලවත් කරමු! (Path Variables & Request Params SC Guide)

කොහොමද යාලුවනේ, ඔයාලා හැමෝම සැප සනීපෙන් ඉන්නවා නේද?

අද අපි කතා කරන්න යන්නේ software engineering ක්ෂේත්‍රයේ, විශේෂයෙන්ම REST API හදනකොට අපිට නැතුවම බැරි, හරියටම කිව්වොත් දිනපතාම වගේ පාවිච්චි කරන concepts දෙකක් ගැන: ඒ තමයි Path Variables සහ Request Params.

ඔයාලා API එකක් හදනවා කියන්නේ, හරියට කඩේකට ගිහින් බඩු ගන්නවා වගේ වැඩක්. සමහර වෙලාවට අපි කියනවා "අපේ පරණ ත්‍රීවිලර් එකට අලුත් ටයර් ටිකක් දෙන්න" කියලා. මෙතන "පරණ ත්‍රීවිලර් එක" කියන්නේ අපි හරියටම identify කරන දෙයක්. තව වෙලාවට අපි කියනවා "ටයර් ටිකක් ඕන, ඒත් පාට කළු වෙන්න ඕන, මිල රුපියල් 10,000ට අඩු වෙන්න ඕන" කියලා. මෙතන අපි දෙන්නේ අමතර filters ටිකක්.

මේ Path Variables සහ Request Paramsත් වැඩ කරන්නේ ඔය වගේම තමයි. එකකින් අපි resource එකක් identify කරනවා, අනිත් එකෙන් අපි ඒ request එක modify කරන්න අවශ්‍ය අමතර විස්තර දෙනවා. අපි මේ දෙක ගැන ටිකක් ගැඹුරින් කතා කරමු.

Path Variables සහ Request Params කියන්නේ මොනවාද?

සරලවම කිව්වොත්, මේ දෙකම Client එකේ ඉඳන් Server එකට data යවන ක්‍රම දෙකක්. ඒත්, ඒ දෙක පාවිච්චි කරන අවස්ථා සහ ඒවායේ අරමුණු වෙනස්.

Path Variables (@PathVariable)

Path Variable එකක් කියන්නේ URL Path එකේම තියෙන කොටසක්. මේවා ගොඩක් වෙලාවට පාවිච්චි කරන්නේ යම්කිසි නිශ්චිත resource එකක් (a specific resource) හඳුනාගන්න. උදාහරණයක් විදිහට, ඔයාලට System එකේ ඉන්න user කෙනෙක්ගේ විස්තර ඕන නම්, ඔයාලා කියනවා "මට user ID 123 තියෙන user ගේ විස්තර ඕන" කියලා. මේ "123" කියන එක තමයි Path Variable එක. මේක API call එකේදී මෙහෙම පෙනේවි:

GET /users/123

මේකෙන් කියවෙන්නේ users කියන collection එකෙන්, 123 කියන ID එක තියෙන user ව හොයන්න කියන එකයි.

Request Params (@RequestParam)

Request Params (හෝ Query Parameters) කියන්නේ URL එකේ Path එකෙන් පස්සේ "?" සලකුණෙන් පටන් අරගෙන, "&" සලකුණෙන් වෙන් කරලා දෙන key-value pairs ටිකක්. මේවා ගොඩක් වෙලාවට පාවිච්චි කරන්නේ filter කරන්න, sort කරන්න, paginate කරන්න, නැත්නම් අමතර, optional data provide කරන්න. උදාහරණයක් විදිහට, ඔයාලට System එකේ ඉන්න "active" user ලා විතරක් ඕන නම්, නැත්නම් "නම 'John' කියලා පටන් ගන්න user ලා" විතරක් ඕන නම්, මේවා Request Params විදිහට දෙන්න පුළුවන්:

GET /users?status=active&name_starts_with=John

මේකෙන් කියවෙන්නේ users ලා ටිකක් හොයන්න, ඒත් status එක active වෙන්න ඕන, නම John කියලා පටන් ගන්න ඕන කියන එකයි. Google එකේ search කරනකොට URL එකේ පේනවා නේද ?q=search_term&sourceid=chrome වගේ. ඒවත් Request Params තමයි.

Path Variables ක්‍රියාත්මක වන හැටි (@PathVariable)

අපි Spring Boot project එකක් ඇතුලේ මේක කොහොමද පාවිච්චි කරන්නේ කියලා බලමු. හිතන්න අපිට Product එකක විස්තර ගන්න API එකක් ඕන කියලා. ඒ Product එක අපි හොයන්නේ ඒකේ ID එකෙන්.

Code Example:

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

@RestController
public class ProductController {

    // Assume a service layer or repository for actual data fetching
    // For simplicity, we'll just return a dummy string here
    
    @GetMapping("/products/{id}")
    public String getProductById(@PathVariable Long id) {
        // In a real application, you'd fetch product from a database
        // using the provided 'id'
        return "Product details for ID: " + id;
    }

    @GetMapping("/categories/{categoryName}/products/{productId}")
    public String getProductInCategory(
            @PathVariable String categoryName,
            @PathVariable Long productId) {
        
        return "Fetching product " + productId + 
               " from category " + categoryName;
    }
}

Explanation:

  • @GetMapping("/products/{id}"): මෙතන {id} කියන එකෙන් කියවෙන්නේ මේ Path එකේ මේ කොටස variable එකක් කියන එකයි.
  • @PathVariable Long id: මේ Annotation එකෙන් Spring Framework එකට කියනවා URL එකේ තියෙන {id} කියන Path Variable එක Controller Method එකේ id කියන parameter එකට Map කරන්න කියලා. ඒ වගේම ඒක Long type එකක් විදිහට auto convert වෙනවා.
  • දෙවෙනි උදාහරණයෙන් පේනවා වගේ, අපිට එක request එකක Path Variables කිහිපයක් පාවිච්චි කරන්නත් පුළුවන්.

වැදගත් දෙයක්: Path Variables හැමවෙලාවෙම required (අවශ්‍ය) වෙනවා. මොකද ඒවා resource එක identify කරන්න පාවිච්චි කරන නිසා. ID එකක් නැතුව Product එකක් හොයන්න බෑ නේද?

Request Params ක්‍රියාත්මක වන හැටි (@RequestParam)

දැන් අපි බලමු Request Params කොහොමද පාවිච්චි කරන්නේ කියලා. හිතන්න අපිට System එකේ තියෙන හැම Product එකක්ම ගන්න ඕන, ඒත් ඒවා filter කරන්න, නැත්නම් limit කරන්න පුළුවන් වෙන්න ඕන කියලා.

Code Example:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;

@RestController
public class ProductCatalogController {

    private List<String> allProducts = List.of("Laptop", "Mouse", "Keyboard", "Monitor", "Printer", "Webcam");

    @GetMapping("/products")
    public List<String> getProducts(
            @RequestParam(required = false) String category,
            @RequestParam(required = false, defaultValue = "5") int limit,
            @RequestParam(required = false) String search) {

        List<String> filteredProducts = new ArrayList<>(allProducts);

        if (category != null && !category.isEmpty()) {
            // In a real app, you'd filter by category from DB
            // For this example, let's just add a dummy product based on category
            if ("electronics".equalsIgnoreCase(category)) {
                filteredProducts.add(0, "Smartphone (Electronics)");
            } else if ("office".equalsIgnoreCase(category)) {
                filteredProducts.add(0, "Desk Lamp (Office)");
            }
        }

        if (search != null && !search.isEmpty()) {
            filteredProducts = filteredProducts.stream()
                                .filter(p -> p.toLowerCase().contains(search.toLowerCase()))
                                .collect(Collectors.toList());
        }

        // Apply limit
        if (filteredProducts.size() > limit) {
            return filteredProducts.subList(0, limit);
        } else {
            return filteredProducts;
        }
    }
}

Explanation:

  • @GetMapping("/products"): මේ endpoint එක /products path එකට request accept කරනවා.
  • @RequestParam(required = false) String category: මේ Annotation එකෙන් Spring Framework එකට කියනවා URL එකේ තියෙන category කියන Request Param එක Controller Method එකේ category කියන parameter එකට Map කරන්න කියලා. required = false කියන්නේ මේ parameter එක අනිවාර්ය නැහැ කියන එකයි. Client එක මේ parameter එක නැතුව request එකක් එව්වත් Error එකක් එන්නේ නැහැ.
  • @RequestParam(required = false, defaultValue = "5") int limit: මෙතන අපි defaultValue එකකුත් දීලා තියෙනවා. ඒ කියන්නේ Client එක limit parameter එක නොදුන්නොත්, ඒ වෙනුවට 5 කියන value එක Auto-fill වෙනවා.
  • String search: අපි required = false දුන්නේ නැති වුණත්, String වගේ Object type එකක් නම් default එකෙන් required = false වෙනවා (එකේ default value එක null). Primitive types (int, long, boolean) වලට අනිවාර්යයෙන්ම required = false දාන්න ඕන, නැත්නම් parameter එක නැති වෙලාවට error එකක් එන්න පුළුවන්.

How to test this endpoint:

  • All products: GET /products
  • Products filtered by category: GET /products?category=electronics
  • Products with a limit: GET /products?limit=3
  • Products filtered and limited: GET /products?category=office&limit=2
  • Products with search term: GET /products?search=lap

මේ Request Params පාවිච්චි කරලා අපිට එකම endpoint එකක් හරහා විවිධ ආකාරයේ queries Handle කරන්න පුළුවන්. ඒක API එකේ flexibility එක වැඩි කරනවා.

කවදාද මොනවා පාවිච්චි කරන්නේ?

මේක තමයි ලොකුම ප්‍රශ්නය. Path Variables සහ Request Params දෙකම Client එකෙන් Server එකට data අරන් යනවා නම්, කවදාද මොකක් පාවිච්චි කරන්නේ?

සරලව කිව්වොත්:

  • Path Variables:
    • යම්කිසි නිශ්චිත resource එකක් (a specific resource) හඳුනාගන්න පාවිච්චි කරන්න.
    • ඒ resource එකේ අනිවාර්යයෙන්ම තියෙන්න ඕන කොටසක් (integral part) නම්, Path Variable එකක් පාවිච්චි කරන්න.
    • උදාහරණ: /users/{id}, /products/{productId}/reviews, /books/{isbn}.
  • Request Params:
    • resource එකක් search කරන්න, filter කරන්න, sort කරන්න, නැත්නම් paginate කරන්න වගේ දේවල් වලදී පාවිච්චි කරන්න.
    • optional data (අනිවාර්ය නොවන data) යවන්න අවශ්‍ය නම් පාවිච්චි කරන්න.
    • උදාහරණ: /products?category=electronics&price_range=low, /users?page=2&size=10, /posts?authorId=123&sortBy=date.

තවත් සරල උදාහරණයක්:

  • ඔයාලා Library එකකට යනවා "Book ID 456" තියෙන පොත ඉල්ලන්න. මෙතන 456 කියන්නේ Path Variable එකක්. මොකද ඒ පොත හඳුනාගන්නේ ඒ ID එකෙන්.
  • දැන් ඔයාලා කියනවා "Science Fiction genre එකේ, "Fantasy" කියන keyword එක තියෙන, අවුරුදු 2023ට පස්සේ publish කරපු පොත් ටිකක් දෙන්න". මෙතන "Science Fiction", "Fantasy", "2023" කියන ඒවා Request Params. මොකද මේවා පොත් ටික filter කරන්න පාවිච්චි කරන data.

නිගමනය (Conclusion)

ඉතින් යාලුවනේ, ඔයාලට දැන් Path Variables සහ Request Params කියන්නේ මොනවද, කොහොමද පාවිච්චි කරන්නේ, සහ කවදාද මොකක් පාවිච්චි කරන්නේ කියලා පැහැදිලි ඇති කියලා මම හිතනවා. මේ concepts දෙක හරියටම තේරුම් අරන් පාවිච්චි කරන එක හොඳ, clean, සහ maintainable REST APIs හදන්න අතිශයින්ම වැදගත්.

මේවා කියවලා විතරක් මදි, අනිවාර්යයෙන්ම ඔයාලගේම project එකක මේ concepts apply කරලා බලන්න. පොඩි Spring Boot project එකක් හදාගෙන මේ API endpoints හදලා Postman නැත්නම් Insomnia වගේ tool එකකින් test කරලා බලන්න. එතකොට තමයි මේක හොඳටම ඔලුවට යන්නේ.

ඔයාලට මේ ලිපිය ගැන තියෙන ප්‍රශ්න, අදහස්, නැත්නම් මේ ගැන තව මොනවද දැනගන්න ඕන කියලා පහලින් comment එකක් දාගෙන යන්න. ඔයාලගේ feedback එක මට ගොඩක් වටිනවා.

එහෙනම් තවත් අලුත් ලිපියකින් හමුවෙමු! පරිස්සමෙන් ඉන්න!