I've written a simple Yesod Rest Server that persists entities in JSON files. Entities are stored on disk in files named data/..json. For instance retrieveCustomer "1234" should load data from file data/Customer.1234.json.
I'm using a polymorphic function retrieveEntity that can retrieve instances of any data type that instantiate the FromJSON typeclass. At the moment I fill in the type name hardcoded in type-specific functions like retrieveCustomer.
How do I manage to compute the type name dynamically in the generic retrieveEntity? I think I'm basically looking for a Haskell type reflection mechanism which I did not come across so far?
-- | retrieve a Customer by id
retrieveCustomer :: Text -> IO Customer
retrieveCustomer id = do
retrieveEntity "Customer" id :: IO Customer
-- | load a persistent entity of type t and identified by id from the backend
retrieveEntity :: (FromJSON a) => String -> Text -> IO a
retrieveEntity t id = do
let jsonFileName = getPath t id ".json"
parseFromJsonFile jsonFileName :: FromJSON a => IO a
-- | compute path of data file
getPath :: String -> Text -> String -> String
getPath t id ex = "data/" ++ t ++ "." ++ unpack id ++ ex
-- | read from file fileName and then parse the contents as a FromJSON instance.
parseFromJsonFile :: FromJSON a => FilePath -> IO a
parseFromJsonFile fileName = do
contentBytes <- B.readFile fileName
case eitherDecode contentBytes of
Left msg -> fail msg
Right x -> return x
Aucun commentaire:
Enregistrer un commentaire