Skip to content

Configurable Cache-Control #535

Open
@mathiversen

Description

@mathiversen

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions