swagger-js icon indicating copy to clipboard operation
swagger-js copied to clipboard

feat: externalValue resolver

Open mathis-m opened this issue 4 years ago • 9 comments

Content & configuration

https://editor.swagger.io/?url=https://gist.githubusercontent.com/mathis-m/262703ffd14ac670366e603d0143943f/raw/4d4d7f3f5a5ba27c9880344976d7297e600588ce/tm8jDkQ5Cq.txt Swagger/OpenAPI definition:

openapi: 3.0.0
info:
 title: asd
 version: "123"
paths:
 /:
   post:
     parameters:
       - in: header
         name: limit
         schema:
           type: integer
           maximum: 50
         examples:
           max:
             summary: A sample limit value  # Optional description
             externalValue: 'https://gist.githubusercontent.com/mathis-m/ad32902aa510d7e69b4b8d3b02e284a6/raw/613955421088a491231b1c6c7766f0f95a5c5824/vNwATb2zAG.txt'
     requestBody:
       content:
         application/json:
           schema:
             {}
           examples:
             jsonObject:
               summary: A sample object
               externalValue: 'https://gist.githubusercontent.com/mathis-m/e97d480acd5e13455beeba37947d2d8b/raw/9e26dfeeb6e641a33dae4961196235bdb965b21b/z1xx2GHQEY.txt'
         image/png:
           schema:
             type: string
             format: binary
           examples:
             KittenImage:
               externalValue: "https://placekitten.com/200/300"
     responses:
       "200":
         description: OK!
         content:
           application/json:
             schema:
               {}
             examples:
               jsonObject:
                 summary: A sample object
                 externalValue: 'https://gist.githubusercontent.com/mathis-m/e97d480acd5e13455beeba37947d2d8b/raw/9e26dfeeb6e641a33dae4961196235bdb965b21b/z1xx2GHQEY.txt'

Is your feature request related to a problem?

I think #5433 at swagger-ui is only partially a swagger-ui issue! I have tried to integrate externalValue examples (from params, requestBody, response) into the sample generation process. I realized that this value is not resolved, I think swagger-js should resolve this just like it resolves refs. Originally posted by @mathis-m in https://github.com/swagger-api/swagger-ui/issues/5433#issuecomment-797645483 .

Describe the solution you'd like

I think swagger-js should resolve this just like it resolves refs.

Describe alternatives you've considered

Else ways I will implement some resolver that will fetch the raw value hosted behind the externalValue url within swagger-ui

Additional context

#5433 at swagger-ui

I have started implementing this and will create a PR for this if it is appreciated in a few days.

mathis-m avatar Mar 14 '21 18:03 mathis-m

@mathis-m,

You're right, it's not being resolved by swagger-js. If you'd like to contribute some sort of resolution for externalValue there are som rules and complexities involved which I'd like to map in this comment before you commence your work.

1.) The value field and externalValue field are mutually exclusive.

We don't resolve externalValue if value was defined.

2.) externalValue can be relative or absolute URL

externalValue can be either relative or absolute URL. If it's relative it's resolved according to these rules.

3.) externalValue eventual value is not interpreted and is always represented as a string

After we resolve externalValue and fetch it, we don't try to interpret it in any way. By Interpreting I mean trying to parse JSON or YAML strings into JavaScript objects. We always transclude whatever is under externalValue URL as a string. If the file extension is different then .json, '.yamlor.ymlwe shouldbase64 encodethe string before we transclude the resolved value tovalue` field. In future progressive enhancement of this can be implemented processing JSON and YAML into POJO before transclusion.

char0n avatar Mar 15 '21 14:03 char0n

@char0n Would it be ok to remove to resolved externalValue and place the resolved value in the .value path instead.

If it should be placed in .externalValue how could this be accomplished. Plugin seems to be called while externalValue key exists, so my questions is probably how to mark a fullPath to exernalValue as resolved to not call the plugin with it again and again.

mathis-m avatar Apr 05 '21 01:04 mathis-m

IMHO most sense is to place the eventual value of externalValue to value field and rename the externalValue to $externalValue to mark it as resolved and stop the plugin execution. The benefit of this is that original URI of externalValue is still available (if needed via $externalValue field).

char0n avatar Apr 05 '21 14:04 char0n

@char0n https://github.com/swagger-api/swagger-js/pull/2013/commits/2d715a1089cbe65372983f4095965685303f2f88#diff-4c3af2fb862ab7ff642af33fc7b839f031caf87d40fce8653ddce27261e89ad8R136-R139 like this?

mathis-m avatar Apr 05 '21 14:04 mathis-m

@mathis-m yep, seems about right.

char0n avatar Apr 05 '21 15:04 char0n

fine then I proceed implementing guards for value and absolutify for the URL.

mathis-m avatar Apr 05 '21 15:04 mathis-m

Any update on this? It would be really great to have this working soon.

ambition-consulting avatar Jul 26 '21 08:07 ambition-consulting

@ambition-consulting I have little time right now, but you are welcome to pick it up

mathis-m avatar Aug 01 '21 13:08 mathis-m

Updated point 3.) described in proposed technical design of this implementation: https://github.com/swagger-api/swagger-js/issues/1978#issuecomment-799476860

char0n avatar Sep 10 '21 07:09 char0n