Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance Response cache-control header #2784

Open
AMorgaut opened this issue Nov 9, 2021 · 4 comments
Open

Enhance Response cache-control header #2784

AMorgaut opened this issue Nov 9, 2021 · 4 comments
Labels
headers http Supporting HTTP features and interactions param serialization Issues related to parameter and/or header serialization
Milestone

Comments

@AMorgaut
Copy link

AMorgaut commented Nov 9, 2021

I have been trying to use Open API to specify the expected Cache rules for some API routes

While defining such rules through the Expires and/or Pragma headers can be quite simple (a date for Expires & the no-cache constant for Pragma), they are not the modern way to do it. Pragma is deprecated, and Expires is ignored when Cache-Control is defined.

Cache-Control is also nowadays supported by all clients making it the most obvious solution to define the caching rules.

Unfortunately, the current OPEN API Header Object support looks a bit limited for Cache-Control. Using pure JSON Schema definition might produce unexpected behavior without dedicated context for this header or for headers having similar Design.

This header value is defined as a comma-seperated list of properties called directives
If all directives were simple strings I could write something like that if I allowed any of them (or restrict to the on I accept by design)

      responses:
        200:
          description: "The request was successfully treated."
          headers:
            Cache-Control: 
              schema:
                type: array
                items:
                  type: string
                  enum:
                  - public
                  - private
                  - no-cache
                  - no-store
                  - must-revalidate
                  - proxy-revalidate
                  - immutable
                  - no-transform
                  - only-if-cached

If I want my route to prevent response to be cached I can easily design it a more simple way

            Cache-Control: 
              schema:
                type: string
                enum:
                - no-store

Or with the last JSON-Schema edition support of constants

            Cache-Control: 
              schema:
                const: "no-store"

But some of the most important cache control properties are key value pairs like max-age=300

I tried to express it the most reiable still simple way using adavanced JSON Schema feature unfortunately not really well supported (yet?) by Open API implementations

Sample 1

  • Pro:
    • shortest
  • Cons:
    • forbid different property order
    • forbid potentially acceptable other cache-control properties
    • not really the most inspectable
            Cache-Control: 
              schema:
                const: "public, max-age=300"

Sample 2

  • Pro:
    • still short
  • Cons:
    • ⚠️❌ the specification doesn't say how to serialize the object
            Cache-Control: 
              schema:
                const: ["public", {"max-age": 300}]

Sample 3

  • Pro:
    • explicit, no need for const support
  • Cons:
    • very verbose
    • pretty sure enum not well supported for numbers
    • ⚠️❌ the specification still doesn't say how to serialize the object
            Cache-Control: 
              schema:
                type: array
                items:
                  allOf:
                  - type: string
                    enum:
                    - public
                  - type: object
                    properties:
                      max-age:
                        type: number
                        enum:
                        - 300
                      required:
                      - max-age
@karenetheridge
Copy link
Member

I think you want explode: true for that parameter: https://spec.openapis.org/oas/v3.1.0#fixed-fields-9

@AMorgaut
Copy link
Author

AMorgaut commented Dec 5, 2021

I think you want explode: true for that parameter: https://spec.openapis.org/oas/v3.1.0#fixed-fields-9

it doesn't resolve this issue
⚠️❌ the specification doesn't say how to serialize the object

@AMorgaut AMorgaut changed the title Maybe Enhance Response cache-control header Enhance Response cache-control header Jun 30, 2022
@handrews handrews added the param serialization Issues related to parameter and/or header serialization label Jan 28, 2024
@handrews
Copy link
Member

Tagging this with "param s11" as the header object is a subset of the parameter object, so this is an overlapping serialization concern.

@handrews handrews added http Supporting HTTP features and interactions headers labels Jan 29, 2024
@handrews handrews added this to the v3.3.0 milestone Nov 21, 2024
@handrews
Copy link
Member

@AMorgaut (if you are still interested): We are looking at revamping parameter modeling for 3.3 (after a quick 3.2 that isn't adding any features as complicated as this), and I suspect your Sample 3 would be the closest to what we would do.

I think your Sample 1 works as-is in 3.1, or using enum in 3.0, but it has those drawbacks.

I think your Sample 2 and Sample 3 are essentially the same idea, and close to what we are likely to do: Define a JSON Schema data model that maps to the header structure. Notably, the const array-with-nested-object in Sample 2 is valid according to the schema in Sample 3.

If we define HTTP headers as modeled as arrays (because you can have multiple instances in order), simple tokens as strings, and name-value pairs as objects with string values, that would define how the data model relates to serialization. Order-independent constraints can be done using the *Of keywords and maybe contains (although once you throw in contains and multiple things to be contained, it gets pretty verbose). We'll have to put more thought into it, but Cache-Control is a good test case because its value is sometimes a name-value pair (as opposed to having a string value and then name-value parameters after ;).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
headers http Supporting HTTP features and interactions param serialization Issues related to parameter and/or header serialization
Projects
None yet
Development

No branches or pull requests

3 participants