Coder Social home page Coder Social logo

Comments (11)

adamaltman avatar adamaltman commented on June 18, 2024 2

The purpose of Redoc is not to enforce the spec. It is extremely lenient and you may make a lot of errors. Its goal is to render what it can as best as it can. The goal of the lint command here is something else entirely. It's to enforce API design standards including specification compliance.

From the spec:

  1. name MUST NOT be specified, it is given in the corresponding headers map.
  2. in MUST NOT be specified, it is implicitly in header.
  3. All traits that are affected by the location MUST be applicable to a location of header (for example, style).

Source OAS 3.1: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#header-object
Source OAS 3.0: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#header-object

from redocly-vs-code.

adamaltman avatar adamaltman commented on June 18, 2024

Does this show problems if you run openapi lint too?

from redocly-vs-code.

jeremyfiel avatar jeremyfiel commented on June 18, 2024

yes. using beta89 I have the following output

[5] filename-swagger_v1.json:543:5 at #/components/parameters/header_Cache-Control/name

Property name is not expected here.

541 | "header_Cache-Control": {
542 | "description": "Specifies directives that must be obeyed by all caching mechanisms along the request/response chain",
543 | "name": "Cache-Control",
544 | "in": "header",
545 | "schema": {

Error was generated by the spec rule.

[6] filename-swagger_v1.json:544:5 at #/components/parameters/header_Cache-Control/in

Property in is not expected here.

542 | "description": "Specifies directives that must be obeyed by all caching mechanisms along the request/response chain",
543 | "name": "Cache-Control",
544 | "in": "header",
545 | "schema": {
546 | "type": "string"

Error was generated by the spec rule.

[7] filename-swagger_v1.json:535:5 at #/components/parameters/header_ETag/name

Property name is not expected here.

533 | "header_ETag": {
534 | "description": "Defines the entity tag for use with the If-Match and If-None-Match request headers",
535 | "name": "ETag",
536 | "in": "header",
537 | "schema": {

Error was generated by the spec rule.

[8] filename-swagger_v1.json:536:5 at #/components/parameters/header_ETag/in

Property in is not expected here.

534 | "description": "Defines the entity tag for use with the If-Match and If-None-Match request headers",
535 | "name": "ETag",
536 | "in": "header",
537 | "schema": {
538 | "type": "string"

Error was generated by the spec rule.

[9] filename-swagger_v1.json:516:5 at #/components/parameters/header_Last-Modified/name

Property name is not expected here.

514 | },
515 | "header_Last-Modified": {
516 | "name": "Last-Modified",
517 | "in": "header",
518 | "description": "Specifies the date and time the representational state of the resource was last modified",

Error was generated by the spec rule.

[10] filename-swagger_v1.json:517:5 at #/components/parameters/header_Last-Modified/in

Property in is not expected here.

515 | "header_Last-Modified": {
516 | "name": "Last-Modified",
517 | "in": "header",
518 | "description": "Specifies the date and time the representational state of the resource was last modified",
519 | "required": true,

Error was generated by the spec rule.

[11] filename-swagger_v1.json:525:5 at #/components/parameters/header_Content-Language/name

Property name is not expected here.

523 | },
524 | "header_Content-Language": {
525 | "name": "Content-Language",
526 | "in": "header",
527 | "description": "Specifies the languages for which the entity-body is intended ",

Error was generated by the spec rule.

[12] filename-swagger_v1.json:526:5 at #/components/parameters/header_Content-Language/in

Property in is not expected here.

524 | "header_Content-Language": {
525 | "name": "Content-Language",
526 | "in": "header",
527 | "description": "Specifies the languages for which the entity-body is intended ",
528 | "required": false,

Error was generated by the spec rule.

from redocly-vs-code.

jeremyfiel avatar jeremyfiel commented on June 18, 2024

more context on this issue.

OAS 3.x.x supports a header object and the schema does not allow name and in. Otherwise, the schema is semantically identical to the parameter object. The header object is expected in the headers map defined in components>headers and is supposed to be used as Response headers throughout the definition. If I want to send request headers where a requestBody doesn't exist, such as a GET operation using caching headers ETag, If-Match etc.., OAS forces me to use parameters rather than headers components because the headers map is only available in the encoding object under content negotiation of a request body. A GET operation shouldn't have a request body but there are plenty of times I need to use headers in the request.

The bug I reported is mis-identifying parameter objects with the in: header identifier and flagging them as invalid.

{
    "openapi": "3.0.3",
    "servers": [
        {
            "url": "https://__host__/"
        }
    ],
    "info": {
        "description": "Test api",
        "version": "1.0.0",
        "title": "empty title"
    },
    "paths": {
        "/some-path/{aoid}": {
            "get": {
                "description": "some description",
                "tags": [
                    "a tag"
                ],
                "summary": "what it does",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/path_aoid"
                    },
                    {
                        "$ref": "#/components/parameters/query_filter"
                    },
                    {
                        "$ref": "#/components/parameters/header_If-Match"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Ok",
                        "headers": {
                            "ETag": {
                                "$ref": "#/components/headers/ETag"
                            },
                            "Last-Modified": {
                                "$ref": "#/components/headers/Last-Modified"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "parameters": {
            "path_aoid": {
                "name": "aoid",
                "in": "path",
                "description": "a param",
                "required": true,
                "schema": {
                    "$ref": "../../../common/associateOIDType_v01.json"
                }
            },
            "header_If-Match": {
                "name": "If-Match",
                "in": "header",
                "description": "If-Match caching policy",
                "required": true,
                "schema": {
                    "type": "string"
                }
            }
        },
        "headers": {
            "ETag": {
                "description": "Defines the entity tag for use with the If-Match and If-None-Match request headers",
                "schema": {
                    "type": "string"
                }
            },
           "Last-Modified": {
				"name": "Last-Modified",
				"in": "header",
				"description": "Specifies the date and time the representational state of the resource was last modified",
				"required": true,
				"schema": {
					"type": "string"
				}
			}
        }
    }
}

If a parameter object is defined in components>parameters and uses in: header as the identifier, it should be treated as a parameter object, not a header object.

from redocly-vs-code.

RomanHotsiy avatar RomanHotsiy commented on June 18, 2024

I just tried your snippet and I can't see the issue:

image

Make sure you are not referencing headers from parameters and vice versa. This may be the issue.

from redocly-vs-code.

jeremyfiel avatar jeremyfiel commented on June 18, 2024

You can see in the original screenshot where i have everything in parameters and some are having errors and some are not. The snippet was just explaining the issue. In my actual file I'm not using components>headers at all. Only components>parameters

from redocly-vs-code.

RomanHotsiy avatar RomanHotsiy commented on June 18, 2024

In your original file do you reference components>parameters from the headers section?

from redocly-vs-code.

jeremyfiel avatar jeremyfiel commented on June 18, 2024

i am referencing components>parameters from response object > headers map.

from redocly-vs-code.

RomanHotsiy avatar RomanHotsiy commented on June 18, 2024

That's the problem.

Object->headers expects header objects, not parameter objects so openapi-cli correctly reports the name and in fields are not expected there.

I understand your intent and that you do it on purpose but it may mean someone made a mistake and we don't have a way to distinguish.
You have to add some duplication to be spec compliant.

Moreover, this goes against OAS 3 spec. Official OAS 3 json-schema cannot catch this issue though due to json-schema limitations.

If you check the corresponding schema you will notice oneOf that allows either header object or ref object. You have a ref there so the validation pass but json-schema can't validate the destination of $ref. You can check it by pointing $ref to something completely unrelated, e.g. Response Object and your definition will still pass official JSON Schema validation.

If you check the definition of Header object it has additionalProperties: false so it does not allow any other properties.
If you dereference your schema and run it against OAS 3 official JSON Schema it will show you that name and in fields are not expected there.

from redocly-vs-code.

jeremyfiel avatar jeremyfiel commented on June 18, 2024

thanks @RomanHotsiy

I think you're right. I'm OOO but will definitely check that when I return. It makes more sense now why only some headers are showing name and in errors.. they are probably referenced in the Response>Headers object.

from redocly-vs-code.

jeremyfiel avatar jeremyfiel commented on June 18, 2024

@RomanHotsiy
I'm looking at this again and I'm having difficulty convincing myself and others that it's actually a problem.
Swagger, stoplight and redoc are all rendering these headers in the UI as expected, but the linting is failing. Changing all of our specs to clear this error is going to be a tough sell to our design team.

is this behavior correct or does it assume the header pointer and ignore the name/in props?

invalid example
https://redocly.github.io/redoc/?url=https://gist.githubusercontent.com/jeremyfiel/85fd4f39944a472cb6bb60d529e2b602/raw/bef1af5735073d897ef99aaee58382b06f29a67c/openapi-test-headers.json#tag/a-tag

valid example
https://redocly.github.io/redoc/?url=https://gist.githubusercontent.com/jeremyfiel/0ec5f45029e701f66d4c62521d41f24c/raw/363c4c47e0d5bc03742ceca95ab1e0672b0eba4f/openapi-test-headers-in-components.json#tag/a-tag/paths/~1some-path~1{aoid}/get

both have the same output on the UI.

from redocly-vs-code.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.