Aeson Value instance of ToMessage

41 views
Skip to first unread message

2tothe8th

unread,
Feb 1, 2013, 9:10:21 AM2/1/13
to ha...@googlegroups.com
I have the following instance in my code to provide a simple means of returning json.  I'm wondering if it would be worth the dependency to add this to happs proper.  Seems useful on a large enough scale to possibly warrant the extra dependency.

David

instance ToMessage Value where
    toContentType _ = B.pack "application/json; charset=UTF-8"
    toMessage       = encode

Jeremy Shaw

unread,
Feb 1, 2013, 6:02:12 PM2/1/13
to HAppS
It is definitely a useful instance. On the other hand.. it pulls in a
bunch of other packages like attoparsec, vector, unordered-containers,
etc. Maybe we already depend on those.. but if not, that increases the
risk of a failure to install :(

This is a sore spot for Haskell -- though not one with an obvious
solution. We want to make it easy for people to use aeson, but we also
don't want to force people to install something they are not going to
use.

I believe the 'correct' solution would be as follows:

1. leave happstack-server free of any new dependencies
2. add a happstack-aeson library that adds the aeson Value instance
(plus any useful helper functions)
3. have higher level packages like happstack-foundation depend on
happstack-aeson

Then people that want batteries-included can go the
happstack-foundation route and have everything, people who want
everything lightweight can go happstack-server, and people that want
to roll their own batteries-included solution can depend on
happstack-server+happstack-aeson.

Now.. the counter argument is that every significant Happstack
application will eventually require JSON, and the clear winner in the
JSON battle is aeson, and therefore happstack-server should support it
out of the box. There are quite a few json libraries on hackage. A few
years ago, the waters were pretty muddy about who the winner would be
(though aeson seemed like the obvious choice). Is there some reason to
believe that aeson will be dethroned? Or should we consider it the de
facto standard?

Also, I don't really like the ToMessage class -- because it forces us
to either (a) create orphan instances (b) have happstack-server depend
on everything that someone might want. Neither solution is very good.
But, removing ToMessage and replacing it with nothing would be even
worse I think. The other problem with ToMessage is that it implies
there is only one best ToMessage for any given type. However, for some
types, like XML, there are often multiple content-types that would
make sense -- but we are forced to pick just one. (The others can be
supported via newtype wrappers -- but that turns out to be really
clunky for ToMessage instances in my experience). If someone has a
better idea, I'd love to hear it!

- jeremy
> --
> You received this message because you are subscribed to the Google Groups
> "HAppS" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to happs+un...@googlegroups.com.
> To post to this group, send email to ha...@googlegroups.com.
> Visit this group at http://groups.google.com/group/happs?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

David Sargeant

unread,
Feb 2, 2013, 9:43:38 PM2/2/13
to ha...@googlegroups.com
Great response. I like the idea of having a happstack-aeson package. That seems to be a very clean solution, that will make it easy for everyone to use the two packages together.

Jeremy Shaw

unread,
Feb 2, 2013, 11:25:27 PM2/2/13
to HAppS
Unfortunately, it is not entirely clean -- because it uses orphan
instances. In normal situations, when you define a type class instance
you either define the instance in the file that defines the class or
you define the instance in the file that defines the type. This way,
if you have the type and the class imported, you are also certain to
have the relevant class instance imported. Unfortunately, if we put
the instance in Happstack.Server.Instances.Aeson (or something like
that), then you could import Data.Aeson and Happstack.Server, but
forget to import Happstack.Server.Instances.Aeson, then you would get
missing instance errors -- which can be confusing.

But, it is the best solution I know of :) The 'fix' for that confusion
is something like the happstack-foundation package which imports the
extra instances for things like aeson such that when you import
Happstack.Foundation, you get everything. But.. that assumes you want
the particular subset of libraries that happstack-foundation decides
to use.

One thing we have been trying to do since we forked HAppS to happstack
is making things more modular -- so that favors putting
happstack-aeson in its own package. In fact, I would not mind
splitting happstack-server up into even smaller pieces (and then
glueing it back together with higher level packages like
happstack-lite, happstack-foundation, etc).

- jeremy
Reply all
Reply to author
Forward
0 new messages