Search code examples
haskellyesodaesonhaskell-persistent

Custom ToJSON instance for Persistent Key


I am building a web application in Haskell. I am using the persistent library to connect to a postgresql database.

I am using the standard schema definition file system where template Haskell is used to generate types from the schema.

share [mkPersist sqlSettings, mkMigrate "migrateAll"]
  $(persistFileWith lowerCaseSettings "schema")

I have many data types defined in my schema file that look like (fake example):

User json
  email Text

Post json
  owner UserId
  name  Text
  body  Text

The "json" next to "Post" indicates that ToJSON / FromJSON are to be automatically generated by the framework.

I have been using this automatic instance generation for many of my types so that I can serialize them over the network.

My issue: I want to provide a custom instance of ToJSON for the Keys. For example in the above "UserId" would be a "Key User". Every time has such an instance generated for it automatically at the moment "PostId" as "Key Post" etc.

When "Post" is serialized it would convert "owner" from a key to the index number like say "52".

I would like to serialize all of the database keys to a different style. For example instead of producing the number '52' producing the string "fiftytwo" (just an example).

If I did not use code generation I could do something like

instance ToJSON (Key record) where
  toJSON _ = Data.Aeson.String "placeholder"

But this would require not using the automatic code generation because of overlapping instance errors. Perhaps there is a way to tell the code generator not to generate instances of "ToJSON (Key Post)" etc for all the datatypes?

I could also simply write custom instance declarations for every type but this would be very redundant.

I am familiar with using newtypes to have multiple instances of a type class, however this would not fit well into this scenario.

Thanks!


Solution

  • Based by the advice in the comment from haoformayor this issue is now solved. The answer is to fork the persistent-template library and modify the mkKeyTypeDec portion.