I’m new to Haskell and Snap and I want to write a simple bug-tracking application. I set up a Snap project using $ snap init and it works. The problem is that I don’t know how to go any further.
I want to create a snaplet Tickets that uses a database to store bug reports, and use that snaplet in my main web application.
I read the documentation about snaplets but I couldn’t figure out where to put their source code (in the /snaplets directory, I suppose? If so, how do I load them?). Could anybody point me in the right direction?
Are you sure you need to create a separate snaplet for Tickets? The snaplet infrasructure is meant for reusable components such as session management, authentication, database access, admin panels, user management, etc.
Are you going to be using your Tickets self-contained module across multiple web applications? If so, then by all means go ahead and create a snaplet.
In any case, it sounds to me like you are at least in part asking how to organize a project with multiple “modules” or “parts” while using snap. I’ll try to address this below. Please let me know if you feel I have missed the mark.
Assuming you don’t need to create a separate snaplet for Tickets:
For functionality specific to a single site, I think you would be better off creating a few modules and developing the code for the functionality right inside your current application’s package and module hierarchy. Here are a few points on how I have been organizing my snap projects of late:
I put my database-related code under modules in
MyApp.DB.namespace. You could have a
MyApp.DB.Ticketsthat contains alldatabase calls needed for operation on your Tickets module.
I put all UI-related functionality under
MyApp.UI.namespace. Youcould put a
MyApp.UI.Ticketsmodule that contains yourHandlers,your
Splices, yourFormsand so on.To handle forms, I use the excellent digestive-functors library. You may find this blog post helpful if you don’t know them already.
I usually have a shared UI helper library under
MyApp.UI.Helperswhere I place common code used across all/most UI modules.I usually have a shared Form helper library under
MyApp.UI.FormsAny code tangential to the fact that my application exposes a Web UI goes outside the
MyApp.UI.namespace. So if my application needs to perform some offline analyses, I may put them under theMyApp.Analysis.namespace.Once you define and export your Handlers under
MyApp.UI.Tickets, you can go to yourSite.hsfile and wire them into your application at specific routes.For inspiration on how to handle database connections, you can check out the postgresql-simple snaplet.
However, if you do need to create a snaplet:
A snaplet is simply a stand-alone application that uses the
Snap.Snapletinfrastructure, (typically) has its own.cabalfile and (typically) is its own Haskell package. Snap then gives you a way to embed or nest this re-usable, self-contained application in yet another snap application. Think a hierarchy of Russian dolls.Assuming you performed something similar to what I described in the section above, you are now 95% ready to convert to a snaplet. Just name your application snaplet-tickets, expose a
SnapletInitusingmakeSnapletand usenestSnapletin another snap application to include this reusable piece of functionality right there.