Skip to content

fix(reports): generate report via GET, not POST (Bring returns 405 on POST)#63

Merged
crakter merged 2 commits into
masterfrom
claude/bring-api-http-405-gkdsp
Jun 2, 2026
Merged

fix(reports): generate report via GET, not POST (Bring returns 405 on POST)#63
crakter merged 2 commits into
masterfrom
claude/bring-api-http-405-gkdsp

Conversation

@crakter
Copy link
Copy Markdown
Owner

@crakter crakter commented Jun 2, 2026

Problem

The import.orders_freight_bring schedule fails with:

Bring API returned HTTP 405 (-: HTTP 405 (empty error body))

That schedule runs a Reports API chain — listInvoiceNumbers → generate → status → download. The v4 rewrite changed the "generate report" endpoint from GET to POST:

  • v3 (Crakter\BringApi\Clients\Reports\GenerateReport): GET …/reports/api/generate/{cust}/{reportType}, filters as a query string
  • v4 (GenerateReportEndpoint): POST with a JSON body

Bring's /reports/api/generate/... route only accepts GET (per Bring's docs: "To generate a report, do a GET to the supplied URL"). The POST is rejected by Bring's gateway with 405 Method Not Allowed and an empty body — which is why the surfaced message has an empty error code (-) and no error envelope. The two sibling endpoints on the same base path (ListAvailableCustomersEndpoint, ListAvailableReportsForCustomerEndpoint) already use GET; only GenerateReportEndpoint was POST.

Fix

src/v4/Endpoint/Reports/GenerateReportEndpoint.php:

  • method()GET (was POST)
  • parameters now emitted as a query string (queryParameters()) instead of a JSON body
  • updated docblock

Plus a regression test (tests/v4/Endpoint/Reports/GenerateReportEndpointTest.php) asserting the GET method, the .json URL, and query-string placement, and a CHANGELOG.md entry under Unreleased → Fixed.

Verification

  • vendor/bin/phpunit — 201 tests pass (3 new + existing Reports tests green)
  • PHPStan level 8 — clean on the changed file
  • php-cs-fixer — no style changes

Note: not exercised against the live Bring API (no Mybring credentials in CI); verified via Bring's docs, the v3↔v4 diff, and unit tests.

Downstream

crakter/purchase pins this library to a master commit in composer.lock; after merge, run composer update crakter/bringapi there to pick up the fix.

https://claude.ai/code/session_01GwRgBSHYS7hXV7nBgDTanT


Generated by Claude Code

… POST)

Bring's /reports/api/generate/{customer}/{reportType} route only accepts
GET, with the report-type filters passed as query parameters (the sibling
list-available routes on the same base path are GET too). The v4 rewrite
issued a POST with a JSON body, which Bring's gateway rejected with
405 Method Not Allowed and an empty body — surfacing downstream as:

  Bring API returned HTTP 405 (-: HTTP 405 (empty error body))

This broke any caller that generates a report, including the
import.orders_freight_bring schedule (listInvoiceNumbers -> generate ->
status -> download). Switch GenerateReportEndpoint back to GET and emit the
parameters as a query string, restoring v3 GenerateReport behaviour. Adds a
regression test asserting the method, URL and query-string placement.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates GenerateReportEndpoint to use a GET request with query parameters instead of a POST request with a JSON body, resolving a 405 Method Not Allowed error. It also adds unit tests to verify this behavior. The feedback suggests mapping boolean query parameters to literal 'true' or 'false' strings to prevent potential API validation issues, as PHP serializes booleans as '1' or '0' by default.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines 52 to 57
/** @return array<string, mixed> */
#[\Override]
protected function jsonBody(): ?array
protected function queryParameters(): array
{
return $this->parameters === [] ? null : $this->parameters;
return $this->parameters;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

When converting parameters to query string arguments via http_build_query (which is called in AbstractJsonEndpoint::uri()), PHP serializes boolean values as 1 (for true) and 0 (for false). Many APIs, including Bring, expect literal 'true' or 'false' strings for boolean query parameters.

To prevent potential API validation or parsing issues, we should explicitly map boolean values to their string representations ('true'/'false') before passing them to the query string builder.

    /** @return array<string, mixed> */
    #[\Override]
    protected function queryParameters(): array
    {
        return array_map(
            fn ($value) => is_bool($value) ? ($value ? 'true' : 'false') : $value,
            $this->parameters
        );
    }

Bring's report filters go over the wire as query parameters; PHP's
http_build_query serialises booleans as 1/0, which Bring's validation
rejects. Map bool values to the literal strings "true"/"false" before
building the query string, mirroring the explicit bool handling in
ListInvoiceNumbersEndpoint. Addresses PR review feedback.
@crakter crakter merged commit 6075199 into master Jun 2, 2026
18 checks passed
@crakter crakter deleted the claude/bring-api-http-405-gkdsp branch June 2, 2026 16:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants