Configurable Cache-Control

Open
#535 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Feature
Clarity
Needs clarification
Activity status
Stale
Tech stack
graphql, postgresql, rust
Domain
api, database

Research direction

Begin by reviewing pg_graphql's existing comment-based configuration for schemas, tables, columns, computed fields, and functions, then trace how GraphQL responses are assembled. Resolve the open questions about precedence, supported Cache-Control values, and response placement before defining tests for the global and override examples.

Written by the indexing model from the issue text.

Description

documentation

Summary

I'd like pg_graphql to return information on how the returned data should be cached, with inspiration from how it's been done in Async GraphQL.

Rationale

It would be highly beneficial if you could configure cache-control with the extension so that the consuming server/client doesn't have to implement such logic. This allows for centralized cache control management and ensures consistency across different clients/servers.

Design

This is how I imagine it:

  1. You can set a global cache_control that acts as the default, similar to how you set inflect_names.
  2. Override the global default with a table cache_control.
  3. Override the global default and the table default with a field/computed field cache_control.
  4. Override the global default with a function cache_control.

Examples

Global default

comment on schema "public" is
e'@graphql({"inflect_names": true, "cache_control": "public, max-age=60"})';

Table override

comment on table "person" is
e'@graphql({"cache_control": "max-age=30"})';

Field override

comment on column "person".password is
e'@graphql({"cache_control": "private, max-age=0"})';

Computed field & functions override

comment on function public._role is
e'@graphql({"cache_control": "public, max-age=30"})';

Req example

{
  personCollection(first: 1) {
    edges {
      node {
        id
        username
        password
        role
      }
    }
  }
}

Res example

{
  "data": {
    "personCollection": {
      "edges": {
        "node": {
          "id": 1,
          "username": "kalle",
          "password": "qwerty",
          "role": "user"
        }
      },
    }
  },
  "cacheControl": "private, max-age=0"
  "errors": []
}

Since the client requested the field password, the default value is overwritten and private, max-age=0 takes precedence. I chose to use the default browser header formatting with a single key-value over a full JSON. This requires a little more work in the extension to parse each string and calculate the final output, but I think it will provide a better experience from the server's perspective as it can just take the value and use that in the response to clients further down the line.

Drawbacks

There will be more logic/code inside the extension.

Alternatives

If this is not provided by the extension itself, then the servers/clients need to parse and evaluate the request/response to decide on how the data can be cached. I've not found a good solution for doing so other than writing my own logic, which doesn't live up to the potential of the fine-grained control described above.

Unresolved Questions

  1. Should the cache-control values be strings or objects in the comments?
  2. Where should the cache-control info be in the final response? In the top-level JSON object next to data and errors?
  3. What cache-control fields/options should be supported? Async Graphql only support public/private and max-age. Should pg_graphql support the same or more?

Thank you for publishing & maintaining this extension!

Dominant language
Rust
Stars
3.4k
Forks
141
Avg merge
19m
Merged PRs (30d)
2

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from supabase/pg_graphql

All issues in supabase/pg_graphql

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.