News aggregator

Alp Mestanogullari: Rethinking webservice and APIs in Haskell: servant 0.2

Planet Haskell - Mon, 12/08/2014 - 6:00pm

Earlier this year, I announced the first version of servant. The goal was to speed up webservice development by getting rid of as much boilerplate as possible. It definitely was an improvement but not quite enough. Assisted this time with Sönke Hahn (of Nikki and the Robots fame) and Julian Arni, two of my now ex-coworkers, we completely rewrote everything and came up with a new way to describe webservices APIs in Haskell. This post introduces servant 0.2, which now lives in its own github org.

<section class="level1" id="webservice-apis-as-types"> Webservice APIs as types

The meat of the new servant is the fact that we now describe webservice APIs as types. And we write these types by combining “API combinators”, that each have a precise meaning. We use type-level string literals for static fragments of an endpoint.

Let’s build a webservice to manage an imaginary userbase.

data User = User { firstName :: !Text , lastName :: !Text } deriving (Eq, Show, Generic) instance ToJSON User instance FromJSON User -- corresponds to: GET /users -- returning a JSON-encoded list of User's. type UserAPI = "users" :> Get [User] userAPI :: Proxy UserAPI userAPI = Proxy server :: Server UserAPI server = listUsers where listUsers = return $ Data.Map.elems users users :: Data.Map.Map Int64 User users = Data.Map.fromList [ (0, User "john" "doe") , (1, User "jane" "doe") ] -- spin up a warp server that serves our API main :: IO () main = run 8080 (serve userAPI server)

Endpoints are separated from one another with :<|>, similar to Alternative’s <|> separating alternative parsers. URL Captures, GET parameters, request bodies and headers are strongly typed and only made available to server handlers by explicit mentions in the type for the corresponding endpoint. They automatically become arguments to the handler functions.

Here’s our previous example expanded to make use of these few features.

data User = User { firstName :: !Text , lastName :: !Text } deriving (Eq, Show, Generic) instance ToJSON User instance FromJSON User -- list all users: GET /users type UserAPI = "users" :> Get [User] -- view a particular user: GET /users/:userid :<|> "users" :> Capture "userid" Int64 :> Get User -- search for users: GET /users/search?q=<some text> :<|> "users" :> "search" :> QueryParam "q" Text :> Get [User] userAPI :: Proxy UserAPI userAPI = Proxy server :: Server UserAPI server = listUsers :<|> viewUserById :<|> searchUser where listUsers = return $ Data.Map.elems users -- the captured userid gets automatically passed to this function viewUserById userid = maybe (left (404, "user not found")) return $ Data.Map.lookup userid users -- the 'q' GET parameter's value automatically passed to this function, -- if present. searchUser Nothing = return [] -- no ?q=something specified searchUser (Just q) = return . Data.Map.elems . Data.Map.filter (userLike q) $ users userLike q usr = q `isInfixOf` firstName usr || q `isInfixOf` lastName usr users :: Data.Map.Map Int64 User users = Data.Map.fromList [ (0, User "john" "doe") , (1, User "jane" "doe") ] -- spin up a warp server that serves our API main :: IO () main = run 8080 (serve userAPI server)

This combinator-based approach lets us define server-side behavior and data-dependency with types, letting the library handle all the GET parameter/capture/request body extraction and letting you worry only about what you need to do with these values. But that doesn’t stop there. servant can also generate Haskell and Javascript functions to query servant webservices and API docs.

</section> <section class="level1" id="want-to-read-more-about-this"> Want to read more about this?
  • We have a Getting Started slideshow that walks you through the basics of the library.
  • We have haddocks for the 4 packages that are full of examples and explanations.
    • servant, API types and serving
    • servant-client, for generating haskell functions to query APIs automatically
    • servant-jquery, for generating javascript functions to query APIs automatically
    • servant-docs, for assistance in API docs generation
</section> Posted on December 9, 2014
Categories: Offsite Blogs

Type systems and logic

Haskell on Reddit - Mon, 12/08/2014 - 4:38pm
Categories: Incoming News

Should I use pwstore-fast?

Haskell on Reddit - Mon, 12/08/2014 - 3:16pm

Hi,

I'm relatively new to Haskell. I convinced my employers that we should use it for an M2M we're building internally. I've been happily hacking away for a couple months and enjoying every second.

Today I came to a question that I know I cannot get wrong: how should I hash my passwords?

I've used the SHA library for computing shasums on file transfers so I started there, but I'd like the library to also take care of some of the other cruft of password management.

pwstore-fast seems to do just that. The interface looks very simple and appealing, but I still don't know how to vet a Haskell library. I checked out the Github page and saw it had been a while since the last commit, but that doesn't necessarily tell me anything about the quality.

So I guess I have three questions: * Is there a standard library everyone is using for password hashing? * Is pwstore-fast a trusted and effective one? * Does anyone have tips for vetting libraries short of reading the source code and assuming I'll know if it's right?

Thanks!

Edit: Looking a little closer in Github, it appears that the project is more active than it first seemed. There was a PR as recent as October 3. I had only looked at the releases page, but the last release there is 2.3 whereas the most recent on Hackage is 2.4.4

submitted by hans2504
[link] [12 comments]
Categories: Incoming News

FP Complete: Dropping GHC 7.4 support in FP Haskell Center

Planet Haskell - Mon, 12/08/2014 - 12:00pm

When we released FP Haskell Center 3.1, we deprecated our support for GHC 7.4. Till now, we've left that support in place to give users a grace window for upgrading to GHC 7.8. I'm announcing our plans to fully remove GHC 7.4 support in a near release, most likely FP Haskell Center 3.3.

One of the main reasons we are removing support is that the library versions compatible with GHC 7.4 are no longer being maintained.

If you are still actively using GHC 7.4 on FP Haskell Center, and would like us to consider extending its lifetime, please let us know (via the feedback link at the top of this page) in the next few weeks.

Categories: Offsite Blogs

Language is not important

Haskell on Reddit - Mon, 12/08/2014 - 10:36am
Categories: Incoming News

The GHC Team: GHC Weekly News - 2014/12/08

Planet Haskell - Mon, 12/08/2014 - 9:33am

Hi *,

Once more, it's time for some news about GHC! This week's regularly scheduled programming (get it?) has brought you...

Closed tickets this week include: #9850, #9005, #9828, #9833, #9582, #8935, #9186, #9480, #9497, #7908, #4347, #3977, #3859, #3844, #3814, #3771, #3739, #2182, #9812, #4921, #7947, #9240, #5401, #3625, #3517, #9444, #9142, #3447, #8894, #3065, #3191, #2697, #2836, #5443, #7736, #2489, #2456, #2204, #9777, #9859, #9869, #9808

Categories: Offsite Blogs

Douglas M. Auclair (geophf): 10 programming challenge sites

Planet Haskell - Mon, 12/08/2014 - 3:30am
Okay. Whoa!

I saw this off the twitter feed: Ten programming challenge sites

And, from it, I have a new love affair: rosalind.info, a problem-solving site for bioinformatics. I love it. What's not to love!
Categories: Offsite Blogs

Doctest v. HSpec v. HTF v. other?

Haskell on Reddit - Sun, 12/07/2014 - 10:11pm

What is your test system of choice and for what reasons? Bonus points i you can point to an "ELI5"-like tutorial on your system of choice. ;-)

submitted by throwaway23478932
[link] [16 comments]
Categories: Incoming News

What is an intermediate haskell programmer?

Haskell on Reddit - Sun, 12/07/2014 - 8:01pm

What do you think and intermediate haskell programmer knows? If you are beyond intermediate, what did you know at that moment? Could you provide examples of intermediate haskell code?

Thanks in advance.

Categories: Incoming News

Oliver Charles: 24 Days of GHC Extensions: Type Operators

Planet Haskell - Sun, 12/07/2014 - 6:00pm

As GHC gradually adopts more and more extensions that allow us to do dependently typed programming in Haskell, it’s natural that we’d like be more expressive at the type level. Today, we’ll look at the type operators, which allows us to use more natural syntax when we write our types.

The extension itself is straight forward. As the documentation mentions, ordinarily an operator doesn’t mean anything special when used in types - GHC would interpret operators as type variables, not particularly useful! However, now that we’ve got some support for type level literals, it’s desirable to concisely type out computations using infix operators (for example, addition and multiplication of natural numbers).

Recently, I was working with a little templating engine using a variant of data types a la carte. I wanted to be able to write templated emails, where I can compose emails from text fragments and variables that need to be filled in later. However, not all emails have the same variables - a registration email doesn’t have the same variables as a booking confirmation email. To work with this, I decided to use data types a la carte to represent open data types.

If you’re new to this method of programming, we’re essentially breaking apart a data type into a combination of functors. For my email templating, I use the following:

data I a = I { unI :: a } data Var a x = Var { unK :: a }

I is the identity functor - we use this to insert text literals. Var is a constant functor - it ignores the data under the functor, instead choosing a variable as a placeholder. The last remaining piece of the puzzle is the ability to combine literal text with placeholders. We can do this with one more functor - the sum functor:

data Sum f g a = InL (f a) | InR (g a)

Armed with this, we are free to write our emails:

data UserVar = UserName | UserEmail email :: [Sum (Var UserVar) I Text] email = [ InR (I "Dear "), InL (Var UserName), ", thank you for your recent email to Santa & Santa Inc."]

However, the type of email templates becomes messier when we have multiple variables:

data ChristmasVar = ChristmasPresent email :: [Sum (Sum (Var UserVar) (Var ChristmasVar)) I Text] email = ...

What is… Lisp?! Instead, we can define an infix operator, and the type becomes a little more readable:

email :: [(Var UserVar + Var ChristmasVar + I) String] email = [ "Dear " , var UserName , ", thank you for your recent email to Santa & Santa Inc." , "You have asked for a: " , var ChristmasPresent ]

There’s more work that’s needed to complete the email templating, and a full code listing can be found on Github. However, hopefully you can see how a fairly obvious extension (opening up the restrictions on how we write our type signatures) can find its way into some interesting applications.

This post is part of 24 Days of GHC Extensions - for more posts like this, check out the calendar.

Categories: Offsite Blogs