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

Set response and request schemas without declared structure? #96

Closed
aosderzhikov opened this issue Feb 28, 2024 · 6 comments
Closed

Set response and request schemas without declared structure? #96

aosderzhikov opened this issue Feb 28, 2024 · 6 comments

Comments

@aosderzhikov
Copy link

Hi, very nice lib!

My app knows about response format only during runtime(it takes it from config file). So I cant declare response format with struct.
Here is any way how I can set response schema with json, yaml, map or something else?

getOp, _ := reflector.NewOperationContext(http.MethodGet, "/user/{id}")
getOp.AddReqStructure(new(struct {
	ID string `path:"id"`
}))

getOp.AddRespStructure()  // <- put json, yaml, map or something else here
@vearutop
Copy link
Member

Please check if virtual structure works for your case.

@aosderzhikov
Copy link
Author

Thanks, I found this useful! There is a way to add response structure with raw yaml or json?

Like:

getOp.AddRespStructure(`
response:
  type: object
  properties:
    field1:
      type: string
    field2:
      type: integer
.....`) 

@vearutop
Copy link
Member

vearutop commented Mar 5, 2024

Hi, you can use jsonschema.RawExposer to provide raw schema, please check an example.

type rawExposer func() ([]byte, error)

func (r rawExposer) JSONSchemaBytes() ([]byte, error) {
	return r()
}

func TestReflector_AddOperation_rawSchema(t *testing.T) {
	r := openapi31.NewReflector()
	oc, err := r.NewOperationContext(http.MethodPost, "/foo")
	require.NoError(t, err)

	oc.AddRespStructure(rawExposer(func() ([]byte, error) {
		return []byte(`{"type":"object","properties":{"foo":{"type":"integer"}}}`), nil
	}), openapi.WithHTTPStatus(http.StatusAccepted))

	require.NoError(t, r.AddOperation(oc))

	assertjson.EqMarshal(t, `{
	  "openapi":"3.1.0","info":{"title":"","version":""},
	  "paths":{
		"/foo":{
		  "post":{
			"responses":{
			  "202":{
				"description":"Accepted",
				"content":{
				  "application/json":{
					"schema":{"$ref":"#/components/schemas/Openapi31TestRawExposer"}
				  }
				}
			  }
			}
		  }
		}
	  },
	  "components":{
		"schemas":{
		  "Openapi31TestRawExposer":{"properties":{"foo":{"type":"integer"}},"type":"object"}
		}
	  }
	}`, r.SpecSchema())
}

(Beware of definition name collisions when using same Go type to expose different schemas, perhaps this can be improved on jsonschema-go side).

@aosderzhikov
Copy link
Author

But it only works for JSON? Any way to do the same with YAML?

@vearutop
Copy link
Member

vearutop commented Mar 6, 2024

hmhm, I considered YAML as an unnecessary "convenience" format that does not need first-class support, being just another form of JSON, so nothing like YAMLSchemaBytes() exists

but I think it is easy to make a helper function that would take YAML, convert it to JSON and expose as JSONSchemaBytes()

@aosderzhikov
Copy link
Author

Okey, thank you very much for answers, you helped me a lot!

Maybe it's a good point to add new examples in the documentation :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants