Open karls opened 7 years ago
Hey @karls
I believe sparse fieldsets should be possible by defining your datatype with Maybe
fields, then hydrating it appropriately based on the query params found in the request. If we look at the datatype used in one of the provided examples, we see User
defined as
data User = User
{ userId :: Int
, userFirstName :: String
, userLastName :: String
} deriving (Eq, Show)
$(deriveJSON defaultOptions ''User)
To support sparse fieldsets, I could change this definition to be something like
data User = User
{ userId :: Int
, userFirstName :: Maybe String
, userLastName :: Maybe String
} deriving (Eq, Show)
-- this bit will hide the Nothings in the resulting JSON
userOptions :: Options
userOptions = defaultOptions { omitNothingFields = True }
$(deriveJSON userOptions ''User)
Then, based on the params found in the request, fill in the Maybe
s appropriately. Aeson already has options for omitting Nothing
fields from its JSON output.
Long story short, I think sparse fieldsets are outside of the scope of this library and more a responsibility of your supplied datatype.
Let me know if this approach sounds like it will work for you. Thanks for checking out this library!
Hey @toddmohney
Sorry for the delay in getting back to you — I became a parent and have been away from my computer for a few weeks. 🎉
Yeah, your outlined solution would work. I suppose there would be two records for the User entity — one that corresponds to the row in the database and one that represents an API response.
It'd be awsome to be able to generate an "API response" record from the "database" record. Something like
data User
= User
{ userId :: Int
, userEmail :: Text
, userPassword :: Text
, userFirstName :: Text
, userLastName :: Text
} deriving (Eq, Show, Generic)
$(deriveResponseRecord ["userEmail", "userFirstName", "userLastName"] ''User)
Which would generate something like this. The field names would have to be slightly different and the ToJSON instance would need to make sure that the field name prefix is dropped properly.
data User'
= User'
{ userId :: Int
, userEmail :: Maybe Text
, userFirstName :: Maybe Text
, userLastName :: Maybe Text
} deriving (Eq, Show, Generic)
instance ToJSON User'
I might look into how to do this with Template Haskell, if time permits.
Hi @karls
Yeah, it's likely that you'd end up with 2 models for the User
; one for the data model, and another for the JSON API representation. I'm a big fan of the layered architecture approach, so modelling the User
in terms of it's concerns (data storage/presentation) has worked out well for me in the past. Reducing boilerplate with a little Template Haskell is certainly an option, too.
Congratulations on your new baby! I hope your family is happy, healthy, and getting some rest! I have a 5 month old at home, so I'm a new dad as well :smile:
Hi @toddmohney,
I'm investigating various structured approaches to building a public API for our web service.
json-api
seems like a good way to do it!I'm wondering, does this library support sparse fieldsets in any way? I couldn't find an obvious way to do it.
Thanks!