Skip to content

Adds Get product handler - #46

Merged
jlpdeveloper merged 2 commits into
mainfrom
get-product-handler
May 5, 2026
Merged

Adds Get product handler#46
jlpdeveloper merged 2 commits into
mainfrom
get-product-handler

Conversation

@jlpdeveloper

@jlpdeveloper jlpdeveloper commented May 5, 2026

Copy link
Copy Markdown
Contributor

Description

Code Rabbit Summary

Summary by CodeRabbit

  • New Features

    • Added endpoint to retrieve a product by ID.
    • Added endpoint to retrieve products filtered by platform.
  • Tests

    • Added test coverage for product retrieval endpoints.

Fixes

Closes #24

Post Deployment Tasks?

… and tests

- Implement `GetProductById` handler for fetching a product by ID.
- Implement `GetProductsByPlatform` handler to fetch products by platform ID.
- Add routes for `/api/products/{id}` and `/api/platforms/{platform_id}/products` to the router.
- Include unit tests for both handlers, covering success and error scenarios.
… requests with examples and documentation.
@jlpdeveloper jlpdeveloper added this to the Phase 2: API Endpoints milestone May 5, 2026
@jlpdeveloper jlpdeveloper self-assigned this May 5, 2026
@jlpdeveloper jlpdeveloper added enhancement New feature or request skip-changelog Won't be added to the release notes labels May 5, 2026
@coderabbitai

coderabbitai Bot commented May 5, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Implements two HTTP GET handlers for retrieving products: one listing products by platform ID and another fetching a product by ID. Handlers include request path parsing, database calls with 10-second context timeouts, error mapping (404 for not found, 400 for invalid params, 500 for database failures), and JSON response serialization. Routes are registered and comprehensive tests are added.

Changes

Product GET Handlers

Layer / File(s) Summary
Handler Implementation
api/product/get.go
Two HTTP handlers: GetProductsByPlatform extracts platform_id, calls h.queries.GetProductsByPlatform, and returns JSON array (nil→empty slice); GetProductById extracts id, calls h.queries.GetProductById, maps pgx.ErrNoRows to 404, and returns JSON product. Both use 10-second context timeouts and set Content-Type: application/json.
Route Registration
router/router.go
Registers new GET /api/platforms/{platform_id}/products endpoint to handler.GetProductsByPlatform alongside existing product CRUD routes.
Tests
api/product/product_test.go
Table-driven tests for both handlers covering: success cases (JSON decoding, status 200, content-type validation), error cases (invalid params→400, not found→404, database failures→500), and nil/empty result normalization.
Request Documentation
_bruno/Product/Get Product By ID.yml, _bruno/Product/Get Products By Platform.yml
Bruno HTTP request definitions with example success responses (200 with product JSON), documented path parameters, inherited auth, and possible-responses tables (200/400/404/500).

Sequence Diagram

sequenceDiagram
    actor Client
    participant Handler as HTTP Handler
    participant Parser as Request Parser
    participant DB as Database Query
    participant Encoder as JSON Encoder

    rect rgba(100, 150, 200, 0.5)
    note over Client,Encoder: GetProductsByPlatform Flow
    Client->>Handler: GET /api/platforms/:platform_id/products
    Handler->>Parser: Extract & parse platform_id
    alt Invalid platform_id
        Parser-->>Handler: 400 Error
        Handler-->>Client: 400 Bad Request
    else Valid platform_id
        Handler->>DB: GetProductsByPlatform(platform_id) + 10s timeout
        alt DB Success
            DB-->>Handler: Product slice (or nil)
            Handler->>Encoder: Convert nil→empty slice, set Content-Type
            Encoder->>Encoder: JSON encode
            Encoder-->>Client: 200 + JSON array
        else DB Error
            DB-->>Handler: Error
            Handler-->>Client: 500 Internal Error
        end
    end
    end

    rect rgba(150, 100, 200, 0.5)
    note over Client,Encoder: GetProductById Flow
    Client->>Handler: GET /api/products/:id
    Handler->>Parser: Extract & parse id
    alt Invalid id
        Parser-->>Handler: 400 Error
        Handler-->>Client: 400 Bad Request
    else Valid id
        Handler->>DB: GetProductById(id) + 10s timeout
        alt pgx.ErrNoRows
            DB-->>Handler: Not Found Error
            Handler-->>Client: 404 Not Found
        else DB Success
            DB-->>Handler: Product
            Handler->>Encoder: Set Content-Type
            Encoder->>Encoder: JSON encode
            Encoder-->>Client: 200 + JSON product
        else Other DB Error
            DB-->>Handler: Error
            Handler-->>Client: 500 Internal Error
        end
    end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • service-atlas/products#45: Implements Delete product handlers and modifies the same router, handler package structure, and Bruno request definitions.

Poem

🐰 A pair of handlers hops along,
One fetches by platform strong,
The other finds a single prize,
With graceful errors—no surprise!
JSON flows and timeouts clear,
The product queries we hold dear. 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Adds Get product handler' is directly related to the main change, which adds two GET product handlers (GetProductsByPlatform and GetProductById) and their integration.
Linked Issues check ✅ Passed The PR fully implements all requirements from issue #24: both handlers parse parameters correctly, use 10-second timeouts, handle errors appropriately, nil-guard results, set Content-Type headers, and encode responses as JSON.
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issue #24 requirements: API handlers, router configuration, tests, and documentation are all in scope for implementing the Get product handlers.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch get-product-handler

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
router/router.go (1)

59-67: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Add integration tests to verify routing behavior and refactor to consolidate platform-related endpoints.

The handler GetProductsByPlatform exists and has unit tests, but the route at line 66 (r.Get("/api/platforms/{platform_id}/products", ...)) is not tested through the router. The unit test manually constructs an HTTP request and invokes the handler directly, bypassing chi's routing logic entirely. This means the actual routing behavior—specifically whether chi's radix tree correctly prioritizes the root-level route over the /api/platforms/* wildcard created by the Mount in registerPlatformCallHandler—is unverified.

Without integration tests, it is unclear whether a GET request to /api/platforms/1/products correctly reaches GetProductsByPlatform or is intercepted by the platform sub-router.

Additionally, the current architecture splits a logically grouped endpoint (/api/platforms/{platform_id}/products) across two separate handler functions in different packages, each with separate database querier dependencies. This can be improved by consolidating platform-related endpoints.

Recommended actions:

  1. Add an integration test that validates the full router correctly handles GET /api/platforms/{platform_id}/products
  2. Refactor to move GetProductsByPlatform into the platform handler or create a shared sub-router pattern to group platform-related concerns logically
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@router/router.go` around lines 59 - 67, Add an integration test that boots
the real chi router (call registerProductCallHandler and
registerPlatformCallHandler as in production) and issues an HTTP GET to
"/api/platforms/1/products" asserting the response comes from the
GetProductsByPlatform handler (verify status/body) to ensure chi routing prefers
the root-level route over the platform sub-router; then refactor routing by
moving GetProductsByPlatform into the platform handler (or create a shared
sub-router under "/api/platforms" that registers the products route) and update
dependencies so the platform handler (or sub-router) uses a single querier
instead of split product/platform queriers, ensuring all platform-related
endpoints are consolidated in registerPlatformCallHandler and removing the
duplicate r.Get("/api/platforms/{platform_id}/products", ...) from
registerProductCallHandler.
🧹 Nitpick comments (1)
api/product/product_test.go (1)

234-398: ⚡ Quick win

Missing zero/negative boundary tests for both new handlers.

TestDeleteProduct explicitly covers "0" and "-1" as invalid IDs (lines 164–174), which implies internal.GetIntFromRequestPath rejects them. TestGetProductById and TestGetProductsByPlatform only test a non-numeric string ("abc") for the invalid-input case, leaving the zero and negative boundaries untested.

As per the coding guideline to assess sufficient code coverage, add the missing cases for consistency:

🧪 Missing test cases to add
 // Inside TestGetProductById tests slice:
+{
+    name:           "Invalid ID (Zero)",
+    id:             "0",
+    mockSetup:      func(m *mockProductQuerier) {},
+    expectedStatus: http.StatusBadRequest,
+},
+{
+    name:           "Invalid ID (Negative)",
+    id:             "-1",
+    mockSetup:      func(m *mockProductQuerier) {},
+    expectedStatus: http.StatusBadRequest,
+},

 // Inside TestGetProductsByPlatform tests slice:
+{
+    name:           "Invalid Platform ID (Zero)",
+    platformID:     "0",
+    mockSetup:      func(m *mockProductQuerier) {},
+    expectedStatus: http.StatusBadRequest,
+},
+{
+    name:           "Invalid Platform ID (Negative)",
+    platformID:     "-1",
+    mockSetup:      func(m *mockProductQuerier) {},
+    expectedStatus: http.StatusBadRequest,
+},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api/product/product_test.go` around lines 234 - 398, Add zero and negative-ID
invalid-input test cases to both TestGetProductsByPlatform and
TestGetProductById: insert table entries with platformID/id values "0" and "-1"
(matching the pattern used in TestDeleteProduct) that call no mockSetup and
expect http.StatusBadRequest; these should exercise the same
internal.GetIntFromRequestPath validation and ensure handlers
GetProductsByPlatform and GetProductById return 400 for zero/negative IDs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@router/router.go`:
- Around line 59-67: Add an integration test that boots the real chi router
(call registerProductCallHandler and registerPlatformCallHandler as in
production) and issues an HTTP GET to "/api/platforms/1/products" asserting the
response comes from the GetProductsByPlatform handler (verify status/body) to
ensure chi routing prefers the root-level route over the platform sub-router;
then refactor routing by moving GetProductsByPlatform into the platform handler
(or create a shared sub-router under "/api/platforms" that registers the
products route) and update dependencies so the platform handler (or sub-router)
uses a single querier instead of split product/platform queriers, ensuring all
platform-related endpoints are consolidated in registerPlatformCallHandler and
removing the duplicate r.Get("/api/platforms/{platform_id}/products", ...) from
registerProductCallHandler.

---

Nitpick comments:
In `@api/product/product_test.go`:
- Around line 234-398: Add zero and negative-ID invalid-input test cases to both
TestGetProductsByPlatform and TestGetProductById: insert table entries with
platformID/id values "0" and "-1" (matching the pattern used in
TestDeleteProduct) that call no mockSetup and expect http.StatusBadRequest;
these should exercise the same internal.GetIntFromRequestPath validation and
ensure handlers GetProductsByPlatform and GetProductById return 400 for
zero/negative IDs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 742fec95-8f8b-41b4-ac52-dfe47c9c7616

📥 Commits

Reviewing files that changed from the base of the PR and between 5a17c71 and e11dc95.

📒 Files selected for processing (5)
  • _bruno/Product/Get Product By ID.yml
  • _bruno/Product/Get Products By Platform.yml
  • api/product/get.go
  • api/product/product_test.go
  • router/router.go

@jlpdeveloper
jlpdeveloper merged commit 756ed95 into main May 5, 2026
3 checks passed
@jlpdeveloper
jlpdeveloper deleted the get-product-handler branch May 5, 2026 01:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request skip-changelog Won't be added to the release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Get Product Handlers

1 participant