Search code examples
haskellservantderived-instances

Customizing the fields generated by automatic derivation of ToSchema


I have the following type:

data Device = Device { _deviceId    :: DeviceId
                     , _deviceName  :: Text
                     , _deviceDtype :: DType }
            deriving (Show, Eq, Generic)
makeFields ''Device
$(deriveJSON (mkOptions "_device") ''Device)

Here I make use of deriveJSON instead of the Generic mechanism, since I need to adapt the name of the fields of the JSON representation for this data type:

-- | Make JSON conversion options.
mkOptions :: String -> Options
mkOptions prefix = defaultOptions { fieldLabelModifier = removePrefix prefix
                                  , unwrapUnaryRecords = True
                                  }

The prefix is needed to generate lenses for the type, but not needed in the JSON representation.

Now I'm trying to generate Swagger documentation, using servant-swagger, which requires a ToSchema instance for Device. Now the problem is that the generated schema will have the given prefixed names of the accessor functions above (_deviceId, _deviceName, _deviceDType). Instead I would to have the modified version (id, name, and dtype).

Is there a way to customize the generic derivation process in such a way?


Solution

  • Not too familiar with servant-swagger and swagger2 but it looks like something like this should do the job:

    import Data.Swagger.Schema
    import Data.Swagger.SchemaOptions
    
    instance ToSchema Device where
      declareNamedSchema =
        genericDeclareNamedSchema
          defaultSchemaOptions {fieldLabelModifier = \fieldLabel -> ...}