Marko
Marko

Reputation: 31375

Haskell as REST server

I would like to try Haskell on a smallish project which should be well suited to it. I would like to use it as a backend to a small ajax application.

Haskell backend should be able to do authentication (basic, form, whatever, ...), keep track of user session (not much data there except for username) and to dispatch request to handlers based on uri and request type. It should also be able to serialize response to both xml and json format, depending on request parameter.

I suppose the handlers are ideally suited for Haskell, since the service is basically stateless, but I don't know where to start for the rest of the story.

Searching hackage didn't give me much hints.

Solution for pure haskell server would be prefered.

Upvotes: 27

Views: 12010

Answers (7)

MtnViewMark
MtnViewMark

Reputation: 5140

I've recently written a production quality web service for internal use. I used the following packages:

  • CGI & FastCGI — for basic web server interfacing
  • UrlDisp — for URL based dispatching
  • HDBC & HDBC-mysql — for database access
  • hexpat — for XML parsing (some requests/responses were XML based)
  • parsec — for configuration file parsing (on the server side)
  • binary &/or cereal — for binary data parsing (some requests/responses were binary based) (though I'd probably use attoparsec now)

Also, for a different project, I'm also using:

  • xhtml — XHTML combinator library

None of these are the highest level components available for Haskell, but they are all quite workable and fairly complete. I avoided the higher-level abstractions since I needed to fit this into an existing larger system, and these packages work just like similar components I've used in other web service projects.

I ran the service as a fastCGI based handler for Apache2 w/mod_fcgid. This appears to be a reliable and efficient set up. I suppose a Haskell based server, compiled together with the service might be faster, but this was pretty reasonable with very little work. I got > 1,400 requests per second on a quad-cpu, 2.6GHz, Linux server.

There are several Haskell pure servers. Most have their own APIs for your service code, though they are all pretty similar. Take a look at:

That's probably a lot to chew on. Let us know how it goes!

Meanwhile, if you want more information you can visit the HaskellWiki.

Upvotes: 17

user519736
user519736

Reputation:

For a server that implements a JSON API I'm using scotty, which builds on WAI+Warp. It is incredibly easy to use, in particular if you've previously built applications with Sinatra.

Upvotes: 9

ertes
ertes

Reputation: 2297

I'm not sure about pure servers, but for small projects, which don't need a full-fledged web framework, I use the WAI library, which is also used by the Yesod framework.

Anyway, even if your application is simple, I would suggest a real framework, because Haskell web frameworks are usually not about being a large library of predefined stuff, but only about providing a clean concept for web applications, be them simple guestbooks or whole AJAX-enabled community applications.

Upvotes: 2

mrsteve
mrsteve

Reputation: 4132

It's now May 2011, just an update on current trends.

I think most web development today is done with yesod or the snap frame work. both are very good and very nice developed (thanks to all the people who are involved!!). further there is also the wrap package.

My small REST example (or resful server). (ok maybe the example is not a real restful server, but it shows how you can handle GET/PUT requests, the rest is up to you..)

If you open http://localhost:8000/mytest in a browser, then "Get request" is displayed. If you make a PUT request with a rest-client (also to localhost:8000/mytest), the content of the request body is stored in "/tmp/restrq.txt".

This code is part of the Site.hs file of the Snap-Framework:

- | Constants
tempFilePath :: String
tempFilePath = "/tmp/restrq.txt"


-- | Helper Functions

-- Bytestring Conversion
strictToLazy :: B.ByteString -> BL.ByteString
strictToLazy x
  | B.null x = BL.Empty
  | otherwise = BL.Chunk x BL.Empty

lazyToStrict :: BL.ByteString -> B.ByteString
lazyToStrict = B.concat . BL.toChunks

getRequestString :: MonadSnap m => m B.ByteString
getRequestString = do message <- getRequestBody
                      return (lazyToStrict message)


-- | Action for PUT request
action :: Application ()
action = do message <- getRequestString
            liftIO $ B.writeFile tempFilePath (B8.append (B8.pack "--- REST BODY ---\n") message)

-- | /mytest (GET and PUT requests possible)
mytest :: Application ()
mytest = method GET (writeBS "Get request") <|> method PUT action


-- | The main entry point handler.
site :: Application ()
site = route [ ("/",            index)
             , ("/mytest", mytest)
             ]
       <|> serveDirectory "resources/static"

Upvotes: 11

Phil
Phil

Reputation: 2299

There are some useful links in this question "What is the ecosystem for Haskell web development?"

Upvotes: 2

Tim Perry
Tim Perry

Reputation: 3096

I'm not sure how low-level you are trying to go. If you want to write your own server you could start from something like this: http://lstephen.wordpress.com/2008/02/14/a-simple-haskell-web-server/

Alternately, if you are looking for a pre-built framework you could try HApps: http://happs.org/

There is also a Ruby-On-Rails port. Turbinado or something.

Lastly, there are some getting started w/ CGI type tutorials. I've used this one: http://www.haskell.org/haskellwiki/Practical_web_programming_in_Haskell (It was also suggested in @mdm's answer)

Good luck!

Upvotes: 2

mdm
mdm

Reputation: 12630

Practical web programming in Haskell. There are a couple of modules you'll find useful, Text.XHtml and Network.CGI.

Upvotes: 1

Related Questions