Open Pitometsu opened 7 years ago
@fizruk can you suggest solution, please?
If you write ToJSON
by hand, you have to write ToSwagger
by hand as well.
@fizruk We should add that note, and an example to http://hackage.haskell.org/package/swagger2-2.1.5/docs/Data-Swagger.html#g:4, shouldn't we?
like
instance ToSchema PaymentOptions where
declareNamedSchema _ = do
mIntSchema <- declareSchemaRef (Proxy :: Proxy (Maybe Int))
mPaymentTypeSchema <- declareSchemaRef (Proxy :: Proxy (Maybe PaymentMethod))
return $ NamedSchema (Just "PaymentOptions") $ mempty
& type_ .~ SwaggerObject
& properties .~
[ ("type", mPaymentTypeSchema)
, ("deffered", mIntSchema)
, ("installment", mIntSchema)
]
& required .~ []
@Pitometsu yes, that seems like a valid instance. Just two comments:
Maybe Int
is the same as for Int
. The difference can only be seen when using Generic
-based deriving — then Maybe
-fields won't show up as required
. When using declareSchemaRef
it really should be the same, so you can just drop Maybe
.required .~ []
is redundant.FromJSON
and ToJSON
instances only handle decoding/encoding, however, that's not enough to construct a Schema
, because parseJSON
and toJSON
methods are not inspectable. So yes, you need to write your own ToSchema
instance and make sure it matches ToJSON
(and FromJSON
).
You have a few options to write your own Schema
:
Generic
-based deriving; in your case you need to tweak SchemaOptions
a bit to get desirable field names:instance ToSchema PaymentOptions where
declareNamedSchema = genericDeclareNamedSchema defaultSchemaOptions
{ fieldNameModifier = f }
where
f "poPaymentType" = "type"
f "poPaymentNet" = "deffered"
f "poInstallment" = "installment"
f name = name
Schema
templates (not relevant for your example);Schema
using sample JSON Value
s.I myself rely mostly on the second option (Generic
-based deriving). Normally I would use some field naming convention + SchemaOptions
and aeson
's Options
that match each other and derive all FromJSON
, ToJSON
and ToSwagger
using those options.
In any case even with deriving mechanisms you need to ensure that ToSchema
really matches ToJSON
. For that I use validateToJSON
. Usually inside a QuickCheck property.
If you also use servant
, consider servant-swagger
's Servant.Swagger.Test
. Specifically validateEveryToJSON
runs validateToJSON
tests for every request/response JSON in your entire API! See test suite example here.
Thank you a lot for detailed answer, things become much more clear now.
I think https://github.com/GetShopTV/swagger2/issues/127#issuecomment-335711767 should be added somewhere in the How to use this library section.
E.g. I have type
And
ToJSON
instance like this:And auto-generated
ToSchema
instance:So, swagger would looks like:
But instead I expect to see something more like:
Without prefixes
The question is: how to do this?