Skip to content

refactor!: share a single HttpMethod enum across the packages - #1678

Merged
spydon merged 3 commits into
mainfrom
chore/shared-http-method
Aug 10, 2026
Merged

refactor!: share a single HttpMethod enum across the packages#1678
spydon merged 3 commits into
mainfrom
chore/shared-http-method

Conversation

@spydon

@spydon spydon commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Why

Four different representations of an HTTP method coexisted across the packages:

Package Representation Values Wire string
functions_client public enum HttpMethod get, post, put, delete, patch method.name.toUpperCase(), open-coded at two call sites
postgrest public enum HttpMethod get, head, post, put, patch, delete String get value => name.toUpperCase()
gotrue @internal enum RequestMethodType get, post, put, patch, delete none, switches to http.Client's get / post / …
storage_client bare String 'GET', 'POST', 'PUT', 'DELETE', 'HEAD' the literal itself

The two public enums shared a name while disagreeing on contents, which forced supabase.dart to export postgrest with hide HttpMethod, making postgrest's enum unreachable through the umbrella library. It also confused the capability matrix, which keys symbols by bare name: it registered HttpMethod for functions and HttpMethod.value for postgrest as if they were one type.

The stringly-typed side had its own cost. storage_client compared method != 'GET' to decide whether to set a JSON content type, in both its Fetch helper and its Iceberg REST catalog.

What changed

One HttpMethod in supabase_common, taking postgrest's shape: the six methods plus the value getter that functions_client used to open-code.

Public surface:

  • functions_client and postgrest re-export the shared enum, so callers of either library see no change.
  • supabase.dart exports postgrest whole again.
  • functions.invocation.method_override registers FunctionsClient.invoke, since the shared enum lives in supabase_common, which .sdk-parse-ignore excludes from the scanned public API surface. A note records that the Dart enum also offers head, which supabase-js does not expose for function invocation.
  • The edge_functions example's "every HTTP method" test skips head, whose response carries no body for the echo function to reflect, and asserts against method.value.

Internal adoption, no public API change since both declarations were @internal:

  • gotrue: RequestMethodType is gone and its roughly 65 call sites use the shared enum. GotrueFetch's dispatch switch gains a head branch to stay exhaustive over six values, wired to http.Client.head, and now skips the JSON content type for head as well as for get. No gotrue call site issues a HEAD today, so that branch is currently unexercised.
  • storage_client: Fetch's private request helpers and the Iceberg catalog's _request take an HttpMethod instead of a String, the wire strings come from .value, and the content-type branch compares enum values. The public wrapper method names (get, post, head, and so on) are unchanged.

Every log line that interpolates a method uses .value, so they keep printing GET rather than the enum's default toString.

The supabase_common pins stay at 0.1.2; melos version rewrites dependents' pins at release time.

Merge order

This targets main directly and does not depend on #1673 or #1677, though it came out of the same review thread. #1673 previously registered HttpMethod and HttpMethod.value, which this PR makes dangling; those registrations have been pruned on that branch, so the two can merge in either order.

Verification

  • dart analyze clean across all packages and examples.
  • dcm analyze reports no issues in any file this PR touches.
  • Suites pass against a local Supabase stack, at the --concurrency=1 the workflow uses: gotrue (479), storage_client (210), postgrest (196), functions_client (48).
  • The compliance symbol, drift and schema checks pass locally with main as the base.

Summary by CodeRabbit

  • New Features

    • Added a shared HttpMethod API covering GET, HEAD, POST, PUT, PATCH, and DELETE.
    • Made HttpMethod available through the relevant client libraries.
    • Added explicit HEAD request support where applicable.
  • Bug Fixes

    • Improved HTTP method serialization for requests.
    • Corrected request content handling for GET and HEAD calls.
    • Updated integration coverage to accurately validate supported methods.

@spydon
spydon requested a review from a team as a code owner August 10, 2026 08:42
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The pull request introduces a shared HttpMethod enum with uppercase serialization. Functions, GoTrue, Storage, and Iceberg clients now use it for HTTP requests. GoTrue adds HEAD handling. Package exports, integration tests, and SDK compliance metadata are updated.

Changes

Shared HTTP method migration

Layer / File(s) Summary
Shared HttpMethod contract and exports
packages/supabase_common/..., packages/functions_client/lib/functions_client.dart, packages/postgrest/lib/postgrest.dart, packages/supabase/lib/supabase.dart
Adds the shared enum and exposes it through the common, Functions, PostgREST, and Supabase libraries.
Functions client method serialization
packages/functions_client/lib/src/functions_client.dart, packages/functions_client/test/functions_dart_test.dart, examples/edge_functions/integration_test/invoke_test.dart
Uses HttpMethod.value for requests and excludes HEAD from response-body method assertions.
GoTrue request API migration
packages/gotrue/lib/src/fetch.dart, packages/gotrue/lib/src/gotrue_*.dart, packages/gotrue/test/fetch_test.dart
Replaces RequestMethodType with HttpMethod across request dispatch and authentication-related APIs. HEAD requests omit JSON content type and body handling.
Storage and Iceberg typed requests
packages/storage_client/lib/src/fetch.dart, packages/storage_client/lib/src/iceberg/iceberg_rest_catalog.dart
Replaces string HTTP methods with HttpMethod values across standard, streaming, multipart, file, and catalog requests.
SDK compliance metadata
sdk-compliance.yaml
References FunctionsClient.invoke and documents the shared enum’s head value.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested labels: v3

Suggested reviewers: tr00d, vinzent03

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: sharing one HttpMethod enum across packages.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/shared-http-method

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.

@QuintinWillison QuintinWillison left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

My Dart's not good enough to comment fully on correctness there, but fully support the reduction of repetition! 💪

@spydon spydon changed the title refactor!: share a single HttpMethod enum through supabase_common refactor!: share a single HttpMethod enum across the packages Aug 10, 2026
spydon added 2 commits August 10, 2026 11:29
functions_client and postgrest each declared their own HttpMethod, with
different values and a different order, so the umbrella library had to
export postgrest with `hide HttpMethod` and the capability matrix could
not tell the two apart in its flat symbol registry.

Both now re-export one enum from supabase_common, taking postgrest's
shape: the six methods plus the value getter that functions_client used
to open-code as name.toUpperCase(). Nothing changes for callers of either
package, and supabase can export postgrest whole again.

functions.invocation.method_override registers FunctionsClient.invoke,
since the shared enum lives outside the scanned public API surface.
gotrue had its own @internal RequestMethodType with the same five values,
and storage_client passed bare method strings around, including a
`method != 'GET'` check to decide on a JSON content type. Both now use the
shared enum, so there is one representation of an HTTP method across the
packages.

Both declarations were internal, so no public API changes. gotrue's
dispatch switch gains a head branch to stay exhaustive, and skips the JSON
content type for it as well as for get.
@spydon
spydon force-pushed the chore/shared-http-method branch from a9bf54e to d34fb96 Compare August 10, 2026 09:33
@spydon
spydon changed the base branch from chore/realtime-constants-internal to main August 10, 2026 09:34
spydon added a commit that referenced this pull request Aug 10, 2026
The shared HttpMethod enum moves into supabase_common (#1678), which the
public API scan excludes, so registering it here would leave a dangling
entry once that lands. FunctionsClient.invoke is the entry point a caller
actually reaches for anyway.
Typing the parameter as HttpMethod turned the interpolation in the log
line into the enum's default toString, so it printed HttpMethod.get where
it used to print GET.
@spydon
spydon force-pushed the chore/shared-http-method branch from d34fb96 to 0a85ab9 Compare August 10, 2026 09:40

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
packages/functions_client/test/functions_dart_test.dart (1)

8-8: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a HEAD request test.

The package tests cover GET, PUT, DELETE, and PATCH, but not HttpMethod.head. Add a request-capturing test that asserts request.method == 'HEAD'. The test does not need to read a response body.

As per coding guidelines, packages/*/test/**/*.dart must add or maintain tests for modified package behavior and run the package's test suite.

🤖 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 `@packages/functions_client/test/functions_dart_test.dart` at line 8, Add a
request-capturing test in the functions client test suite for HttpMethod.head,
asserting the captured request method is 'HEAD' without reading a response body.
Follow the existing GET/PUT/DELETE/PATCH test patterns and run the package test
suite.

Source: Coding guidelines

packages/gotrue/test/fetch_test.dart (1)

201-226: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the new HttpMethod.head behavior.

The fetch implementation adds a HEAD dispatch branch and changes automatic JSON Content-Type handling for GET and HEAD. This test file exercises only HttpMethod.get. Add a focused mock-client test that verifies the HEAD path and confirms that automatic JSON content metadata is not added. Run the GoTrue test suite. Use dart test -j 1 for backend-dependent tests.

As per coding guidelines: packages/*/test/**/*.dart must add or maintain tests for modified package behavior and run the package's test suite; backend-dependent GoTrue tests must run sequentially with dart test -j 1.

🤖 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 `@packages/gotrue/test/fetch_test.dart` around lines 201 - 226, Add a focused
mock-client test near _testFetchRequest that calls GotrueFetch.request with
HttpMethod.head, verifies the HEAD dispatch behavior, and asserts automatic JSON
Content-Type metadata is absent. Follow existing test conventions, then run the
GoTrue package suite with backend-dependent tests executed via dart test -j 1.

Source: Coding guidelines

🤖 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.

Nitpick comments:
In `@packages/functions_client/test/functions_dart_test.dart`:
- Line 8: Add a request-capturing test in the functions client test suite for
HttpMethod.head, asserting the captured request method is 'HEAD' without reading
a response body. Follow the existing GET/PUT/DELETE/PATCH test patterns and run
the package test suite.

In `@packages/gotrue/test/fetch_test.dart`:
- Around line 201-226: Add a focused mock-client test near _testFetchRequest
that calls GotrueFetch.request with HttpMethod.head, verifies the HEAD dispatch
behavior, and asserts automatic JSON Content-Type metadata is absent. Follow
existing test conventions, then run the GoTrue package suite with
backend-dependent tests executed via dart test -j 1.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a75debce-1200-4924-86e3-baa5c3059361

📥 Commits

Reviewing files that changed from the base of the PR and between 0c0bfab and 0a85ab9.

📒 Files selected for processing (24)
  • examples/edge_functions/integration_test/invoke_test.dart
  • packages/functions_client/lib/functions_client.dart
  • packages/functions_client/lib/src/functions_client.dart
  • packages/functions_client/lib/src/types.dart
  • packages/functions_client/test/functions_dart_test.dart
  • packages/gotrue/lib/src/fetch.dart
  • packages/gotrue/lib/src/gotrue_admin_api.dart
  • packages/gotrue/lib/src/gotrue_admin_custom_providers_api.dart
  • packages/gotrue/lib/src/gotrue_admin_mfa_api.dart
  • packages/gotrue/lib/src/gotrue_admin_oauth_api.dart
  • packages/gotrue/lib/src/gotrue_admin_passkey_api.dart
  • packages/gotrue/lib/src/gotrue_client.dart
  • packages/gotrue/lib/src/gotrue_mfa_api.dart
  • packages/gotrue/lib/src/gotrue_oauth_api.dart
  • packages/gotrue/lib/src/gotrue_passkey_api.dart
  • packages/gotrue/test/fetch_test.dart
  • packages/postgrest/lib/postgrest.dart
  • packages/postgrest/lib/src/postgrest_builder.dart
  • packages/storage_client/lib/src/fetch.dart
  • packages/storage_client/lib/src/iceberg/iceberg_rest_catalog.dart
  • packages/supabase/lib/supabase.dart
  • packages/supabase_common/lib/src/http_method.dart
  • packages/supabase_common/lib/supabase_common.dart
  • sdk-compliance.yaml
💤 Files with no reviewable changes (2)
  • packages/postgrest/lib/src/postgrest_builder.dart
  • packages/functions_client/lib/src/types.dart

@spydon
spydon merged commit 23d55c3 into main Aug 10, 2026
43 checks passed
@spydon
spydon deleted the chore/shared-http-method branch August 10, 2026 09:48
spydon added a commit that referenced this pull request Aug 10, 2026
The functions_client enum gained head and reordered its values when it
merged with postgrest's (#1678), so an exhaustive switch stops compiling
and index shifts for post, put and delete.
spydon added a commit that referenced this pull request Aug 10, 2026
Follow-up to #1678, which landed without a migration note.

## Why

Merging the two `HttpMethod` enums changed the one that
`functions_client` exported, and both effects are things a caller can
hit:

- `head` joined the enum, so an exhaustive `switch` over `HttpMethod` in
user code stops compiling. Verified: the analyzer reports
`non_exhaustive_switch_expression`.
- The declaration order changed, so `index` moved for `post`, `put` and
`delete`. That one is silent, which is exactly the kind of change this
guide flags.

Nothing changes for callers who only used postgrest's enum, and no
import paths change, since the shared enum is re-exported from both
packages.

## What changed

One section added to the v3 list in `MIGRATION.md`: 13 lines, two
bullets, no snippets. The shifted indices were read off the runtime
output of iterating the merged enum (`get=0 head=1 post=2 put=3 patch=4
delete=5`) rather than derived by hand.

Docs only, no code changes.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Added support for the `HEAD` HTTP method.
* Standardized HTTP method handling across Functions and PostgREST
integrations.
  * Added uppercase wire-format values for HTTP methods.
* Improved compatibility for sharing HTTP method definitions across
integrations.

* **Documentation**
  * Added migration guidance for updating method-based switches.
* Documented replacing persisted numeric method indices with stable
method names.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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