One of custom types for input path parameter possible? #138
Answered
by
vearutop
pboguslawski
asked this question in
Q&A
-
Is it possible for interactor to have input path parameter
If it's possible - what's the best way to code it for openapi.json and interactor? |
Beta Was this translation helpful? Give feedback.
Answered by
vearutop
Feb 27, 2023
Replies: 1 comment 1 reply
-
Dealing with complex logical schemas ( To make it work, you would need to instrument schema, decoder and validator separately. Please check an example: package main
import (
"context"
"encoding/json"
"log"
"net/http"
"strconv"
"github.com/swaggest/jsonschema-go"
"github.com/swaggest/rest/web"
swgui "github.com/swaggest/swgui/v4emb"
"github.com/swaggest/usecase"
)
type intOrString struct {
isUint bool
u uint64
s string
}
var (
_ jsonschema.RawExposer = intOrString{}
// Customization can also be achieved with other interfaces.
//_ jsonschema.Exposer = intOrString{}
//_ jsonschema.Preparer = intOrString{}
)
// JSONSchemaBytes overrides schema of a magic type.
func (i intOrString) JSONSchemaBytes() ([]byte, error) {
return []byte(`{"oneOf":[{"type":"string","enum":["foo"]},{"type":"integer","minimum":10}]}`), nil
}
// UnmarshalText enables custom decoding for a path/query/header/cookie parameter.
func (i *intOrString) UnmarshalText(text []byte) error {
v, err := strconv.ParseUint(string(text), 10, 64)
if err == nil {
i.isUint = true
i.u = v
return nil
}
i.s = string(text)
return nil
}
// MarshalJSON enables proper JSON schema validation for a magic type.
func (i intOrString) MarshalJSON() ([]byte, error) {
if i.isUint {
return json.Marshal(i.u)
}
return json.Marshal(i.s)
}
func main() {
s := web.DefaultService()
// Declare input port type.
type itemInput struct {
ID intOrString `path:"itemID"`
}
// Create use case interactor with references to input/output types and interaction function.
u := usecase.NewInteractor(func(ctx context.Context, input itemInput, output *struct{}) error {
println(input.ID.isUint, "::", input.ID.u, "::", input.ID.s)
return nil
})
// Add use case handler to router.
s.Get("/items/{itemID}", u)
// Swagger UI endpoint at /docs.
s.Docs("/docs", swgui.New)
// Start server.
log.Println("http://localhost:8011/docs")
if err := http.ListenAndServe("localhost:8011", s); err != nil {
log.Fatal(err)
}
} |
Beta Was this translation helpful? Give feedback.
1 reply
Answer selected by
pboguslawski
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Dealing with complex logical schemas (
*Of
,not
,if
, etc...) is not easy, though it is doable.To make it work, you would need to instrument schema, decoder and validator separately.
Please check an example: