[web-devel] Hoogle Advice

Jeremy Shaw jeremy at n-heptane.com
Tue Jan 25 20:19:17 CET 2011


On Jan 25, 2011, at 12:29 PM, Chris Smith wrote:

> On Tue, 2011-01-25 at 20:10 +0200, Michael Snoyman wrote:
>>> That's one of the main reasons I've designed Yesod and WAI the way I
>>> have. By splitting the project up into so many pieces (Hamlet,
>>> Persistent, authenticate, etc), users get to pick and choose exactly
>>> what they want.
>>>
>>> Yes. Happstack is the same way.
>>
>> Yes, and I'm a fan of that. I just wish that other frameworks (cough,
>> cough) could take a similar approach.
>
> What parts of Snap would you like to see split out into separate
> projects?  Heist is completely independent of Snap.  And snap-server  
> is
> already a separate package from snap-core that handles the low-level
> HTTP stuff, though perhaps the module boundary isn't exactly where and
> like you're accustomed to.

The splitting out of heist is perfect. That made it easy to create  
happstack-heist.

The boundary on the spliting of snap-core and snap-server is not quite  
right in my opinion. It tries to use just two packages where we really  
want three.

The snap-core layer is an odd mix of the low-level and high-level code  
with the middle part split out into snap-server.

The base layer should be 'crackle' which just contains the low-level  
types like Request, Response, etc. And functions that work with just  
those low-level types. This would probably include low-level aspects  
of parsing and creating Cookies, etc. Do happstack, yesod, and snap  
really need their own special cookie parsers? I doubt it.

On top of the 'crackle' layer you build things like snap-server. In  
fact, snap-server could be split into two libraries, snap-server- 
simple and snap-server-libev. Additionally you could have snap-server- 
fastcgi, snap-sever-cgi, etc. They will all export some function with  
a type like:

 > type Backend = Request -> Iteratee ByteString IO Response
 > backend  :: Conf -> Backend

On top of the 'crackle' layer you also build the high level snap- 
framework stuff which contains the other stuff that is current in snap- 
core such as the Snap monad, etc.

Note that the snap-framework stuff does not build on top of the the  
snap-server stuff -- just the crackle layer.

Now, when I build my snap-based application I import snap-framework  
(which likely re-exports the crackle stuff for me), and build my app  
on top of that. A vast majority of the application is server-backend  
agnostic.

In my Main.hs is where I actually import the 'backend' function from  
one of the snap-server-* libraries. This should make it very easy too  
swap out one server backend for another. You basically just import a  
different 'server' function and drop it in (though each server backend  
may have a slightly different Conf type).

 > main = serve (backend backendConf) mySnapApp

Where 'serve' comes from snap-framework (not crackle):

 > serve :: Backend -> Snap () -> IO ()

Or something like that.

The wider advantage of crackle+snap-server-* is that it makes it  
easier to:

  (1) add additional backends
  (2) use the code in other frameworks

Happstack would be very interested in using the crackle layer + the  
snap-server-* components. While happstack can do that right now, it  
just doesn't feel very clean. When we import Snap.Types to get at the  
Request and Response types, it means we also have a bunch of extra  
crap we do not want like the Snap monad.

With crackle+snap-server-* I can import just the pieces I will  
actually use.

This is the exactly model that WAI offers. I can build happstack  
around the WAI package, and then get the warp server or whatever for  
the backend. Basically, crackle is WAI, but which a different name. I  
have heard numerous claims that it is too early to 'standardize' on  
WAI, though I am not clear what the practical differences are.

The essence of WAI is this type:
type Application = Request -> Iteratee B.ByteString IO Response
Which is looks awfully similar to what Snap does. If you unpack the  
Snap monad enough, that is essentially what you end up with. The only  
difference is that you have the Request/Response types from Snap  
instead of from WAI.
What makes the Snap version of the Request/Response types  
fundamentally incompatibly with and superior to WAI?
- jeremy
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/web-devel/attachments/20110125/b9ce9e0b/attachment.htm>


More information about the web-devel mailing list