Haskell as REST server - rest

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.

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:
hack and hack-handler-simpleserver (which has an adapter to call code written to CGI/FastCGI directl: hack-handler-cgi, hack-handler-fastcgi)
Happstack
hyena (which uses the wai interface, and see wai-extra).
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.

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"

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.

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!

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

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.

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

Related

Typesafe RPC shared between client/server but with REST methods

I would like to know if there is a way to join RPC(so client know what he can call and server know what should he respond to) and HTTP Rest(so any other client, without shared codebase can make a call).
There is a lot of http libraries for scala(akka-http, http4s, etc.) and there is good RPC lib autowire. But I see no way to connect them. I know autowire is protocol agnostic, but it's a drawback here, because i would like to routing happened in http layer(e.g akka-http), not rpc(autowire).
I would like to know if it possible. If it is, is there any implementation ongoing?
endpoints is a work in progress in this direction (note: I am the author of this library). It provides means of defining an API made of HTTP endpoints (which verb, URL, etc. to use), and then it provides implementations that use such APIs as a client or as a server. It is compatible with Scala.js, so you can share your API definition between the client side and the server side of your application and benefit from statically type checked remote calls.
It is designed to give you full control over the usage of HTTP features (e.g. caching, headers, authentication, etc.).
Here is a basic API definition with two endpoints:
// POST /my-resources
val create: Endpoint[CreateMyResource, MyResource] =
endpoint(post(path / "my-resources", jsonRequest[CreateMyResource]), jsonResponse[MyResource])
// GET /my-resources/:id
val read: Endpoint[String, Option[MyResource]] =
endpoint(get(path / "my-resources" / segment[String]), option(jsonResponse[MyResource]))
You can then use it as follows from the client-side, to perform an actual call:
val eventuallyResource: Future[MyResource] =
create(CreateMyResource("foo", 42))
val eventuallyResource2: Future[Option[MyResource]] =
read("abc123")

GWT Client Server Communication

I'm wondering whether it is at all possible to make the client ask the server for a given string, and incorporate it into another string ?
I don't see how to do that using the async approach.
As far as I know there is no really simple way to do this, because the i18n machanism of GWT replaces strings at compile-time and not at runtime.
You can try one of the following approaches:
Load the i18n in your entrypoint, store all messages in a local Map and create the Label etc, with the values from you cache. PRO: all GWT standard CONS: one request more, before you can show a translated page
Use JSP and no HTML at serverside. Wthin you jsp can create a JSON from your
message.properties and put it into your hostpage. PRO: You can synchronous read te values CONS: You will need to write a JSP which reads the properties for the correnct language, You will need to write a JSNI method to load the translated values.
Rethink, if you need a different way of translation. The built-in i18n will create tranlated versions of your app at compile-tim
I think I would use the second approach.

Elixir Protocols in Erlang & a Strange Warning

I wanted to write something like ((IStringer)object).ToString() (in C#) in Erlang. After some studying I've learnt that Elixir has something called Protocols that pretty much resembles the same thing of C# (in an inside-out manner). Then I came up with this idea/code in Erlang - which is nice enough to me like:
?stringer(my_val):to_string().
And it either returns the expected value or not_implemented atom!
But 2 questions:
1 - Why nobody use this or promote things based on stateful modules in Erlang? (OTP aside and from talking to some Erlangers they did not know that actually OTP is built around this! So really there is a need to change how Erlang is being taught and promoted. It's possible that I am confused.).
2 - Why I get this warning? That call actually can never fails.
The warning:
stringer.erl:18: Warning: invalid module and/or function name; this call will always fail
stringer.erl:19: Warning: invalid module and/or function name; this call will always fail
stringer.erl:20: Warning: invalid module and/or function name; this call will always fail
The code:
-module(stringer).
-export([to_string/1,sample/0]).
-define(stringer(V), {stringer, V}).
to_string({stringer, V}) when is_list(V) ->
to_string(V, nop);
to_string({stringer, V}) when is_atom(V) ->
to_string(V, nop);
to_string({stringer, _V}) ->
not_implemented.
to_string(V, _Nop) ->
Buffer = io_lib:format("~p",[V]),
lists:flatten(Buffer).
sample() ->
io:format("~p~n", [?stringer([1,2]):to_string()]),
io:format("~p~n", [?stringer(cute_atom):to_string()]),
io:format("~p~n", [?stringer(13):to_string()]).
And the output is:
"[1,2]"
"cute_atom"
not_implemented
I am doing this on Erlang R16 B2 (V5.10.3) 32 bit on Windows 8 64 bit.
The warning you see is an Erlang bug. If Erlang sees you are invoking a function in a literal tuple, it shows the warning. I have seen this while working with Elixir, I have silenced it in Elixir's compiler but forgot to report it to the Erlang team as a bug. Sorry.
The stateful module thing is actually avoided in Erlang by the majority of developers. They were added to support a feature called "parameterized modules", which has then since been removed, but the underlying dispatching mechanism still exists. If you search the Erlang Questions mailing list you can find plenty of discussion on the topic. Note that protocols in Elixir are not implemented like that though.
In fact, it seems your implementation does not seem to add anything compared to a regular function. For example, you could have simply written:
to_string(V) when is_list(V); is_atom(V) ->
Buffer = io_lib:format("~p",[V]),
lists:flatten(Buffer);
to_string(V) ->
not_implemented.
and called the function directly. Your implementation is simply using the classic ad-hoc polymorphism provided by Erlang at the end of the day. The limitation of this approach is that, since dispatch is hardcoded to ?stringer, the only way to extend the to_string/1 behaviour to work with a new data type is to reimplement and replace the whole stringer module.
Here is an example of an issue that helps you ponder about this: if application A defines a "protocol" named stringer, how can applications B and C extend this protocol to their own data types and all be used by application D without loss of functionality?
In very simple words, the way protocols work in Elixir is by making the stringer module an intermediate dispatch module. So the stringer module actually works like this:
to_string(V) when is_list(V) ->
string_list:to_string(V);
to_string(A) when is_atom(A) ->
string_atom:to_string(A);
%% ...
to_string(A) when is_tuple(A) ->
string_tuple:to_string(A).
and imagine that code is wrapped around something that checks if the module exists and fails accordingly if not. Of course, all of that is defined automatically for you by simply defining the protocol. There is also a mechanism (called consolidation) to compile protocols down to a fast dispatch mechanism on releases.

How to describe Input Parameter in a RESTful Web Service

Im developeing a RESTful Service in which Processes can be executed and proivde a resulting calculation. For this i have modeled the process itself as a Resource (Example: /processes/translate). I want to execute the process by sending a GET request with appended Input Parameter as Query Parameter (Example: /processes/translate?input1=xxxx&input2=xxxxx).
Each process has different Input Parameter which are defined during the process creation in the backend. My Question is how should i document or describe which inputs are needed to execute a process in machine readable form. For Example in XML.
Until now ive integrated atom:link elements in the Representation. i thought that maybe including XFORM could be a soluttion?
Best Regards
Andre
I would not model this with a GET. While it's the easier solution, it's also (IMO) the least RESTful. I would have clients POST a document describing what they want you to translate and your service sends them back a URI where their answer can be found (some translations might take a while).
Example (ommiting a lot of HTTP headers/context)
POST /processes/translate
Content-Type: application/xml
...
<translation-request>
<input1 type="type1">....</input1>
<input2 type="type5">....</input2>
</translation-request>
Response:
200 OK
Content-Location: /processes/translate/jobs/1234
....
That's always an interesting question. We have a project called RESTx (http://restx.org), with which you can create RESTful web services very easily. You can write custom component code in either Java or Python and then create RESTful resources by sending parameter sets to the server, which are then stored. Each parameter set gets its own URI, though, so you can always just run the code with those parameters by accessing the new parameter set's URI.
Importantly, the entire RESTful API, is automatically created. RESTx examines the component code and then assembles the API description. We decided to describe parameters in a way that is human as well as machine readable. You can see examples of what that looks like in a browser or in plain JSON.
I'm the lead developer on that, so please feel free to contact me about any questions you might have.

How to version REST URIs

What is the best way to version REST URIs? Currently we have a version # in the URI itself, ie.
http://example.com/users/v4/1234/
for version 4 of this representation.
Does the version belong in the queryString? ie.
http://example.com/users/1234?version=4
Or is versioning best accomplished another way?
Do not version URLs, because ...
you break permalinks
The url changes will spread like a disease through your interface. What do you do with representations that have not changed but point to the representation that has? If you change the url, you break old clients. If you leave the url, your new clients may not work.
Versioning media types is a much more flexible solution.
Assuming that your resource is returning some variant of application/vnd.yourcompany.user+xml all you need to do is create support for a new application/vnd.yourcompany.userV2+xml media type and through the magic of content negotiation your v1 and v2 clients can co-exist peacefully.
In a RESTful interface, the closest thing you have to a contract is the definition of the media-types that are exchanged between the client and the server.
The URLs that the client uses to interact with the server should be provided by the server embedded in previously retrieved representations. The only URL that needs to be known by the client is the root URL of the interface. Adding version numbers to urls only has value if you construct urls on the client, which you are not suppose to do with a RESTful interface.
If you need to make a change to your media-types that will break your existing clients then create a new one and leave your urls alone!
And for those readers currently saying that this makes no sense if I am using application/xml and application/json as media-types. How are we supposed to version those? You're not. Those media-types are pretty much useless to a RESTful interface unless you parse them using code-download, at which point versioning is a moot point.
I would say making it part of the URI itself (option 1) is best because v4 identifies a different resource than v3. Query parameters like in your second option can be best used to pass-in additional (query) info related to the request, rather than the resource.
Ah, I'm putting my old grumpy hat on again.
From a ReST perspective, it doesn't matter at all. Not a sausage.
The client receives a URI it wants to follow, and treats it as an opaque string. Put whatever you want in it, the client has no knowledge of such a thing as a version identifier on it.
What the client knows is that it can process the media type, and I'll advise to follow Darrel's advice. Also I personally feel that needing to change the format used in a restful architecture 4 times should bring huge massive warning signs that you're doing something seriously wrong, and completely bypassing the need to design your media type for change resiliance.
But either way, the client can only process a document with a format it can understand, and follow links in it. It should know about the link relationships (the transitions). So what's in the URI is completely irrelevant.
I personally would vote for http://localhost/3f3405d5-5984-4683-bf26-aca186d21c04
A perfectly valid identifier that will prevent any further client developer or person touching the system to question if one should put v4 at the beginning or at the end of a URI (and I suggest that, from the server perspective, you shouldn't have 4 versions, but 4 media types).
You should NOT put the version in the URL, you should put the version in the Accept Header of the request - see my post on this thread:
Best practices for API versioning?
If you start sticking versions in the URL you end up with silly URLs like this:
http://company.com/api/v3.0/customer/123/v2.0/orders/4321/
And there are a bunch of other problems that creep in as well - see my blog:
http://thereisnorightway.blogspot.com/2011/02/versioning-and-types-in-resthttp-api.html
These (less-specific) SO questions about REST API versioning may be helpful:
Versioning RESTful services?
Best practices for web service REST API versioning
There are 4 different approaches to versioning the API:
Adding version to the URI path:
http://example.com/api/v1/foo
http://example.com/api/v2/foo
When you have breaking change, you must increment the version like: v1, v2, v3...
You can implement a controller in you code like this:
#RestController
public class FooVersioningController {
#GetMapping("v1/foo")
public FooV1 fooV1() {
return new FooV1("firstname lastname");
}
#GetMapping("v2/foo")
public FooV2 fooV2() {
return new FooV2(new Name("firstname", "lastname"));
}
Request parameter versioning:
http://example.com/api/v2/foo/param?version=1
http://example.com/api/v2/foo/param?version=2
The version parameter can be optional or required depending on how you want the API to be used.
The implementation can be similar to this:
#GetMapping(value = "/foo/param", params = "version=1")
public FooV1 paramV1() {
return new FooV1("firstname lastname");
}
#GetMapping(value = "/foo/param", params = "version=2")
public FooV2 paramV2() {
return new FooV2(new Name("firstname", "lastname"));
}
Passing a custom header:
http://localhost:8080/foo/produces
With header:
headers[Accept=application/vnd.company.app-v1+json]
or:
headers[Accept=application/vnd.company.app-v2+json]
Largest advantage of this scheme is mostly semantics: You aren’t cluttering the URI with anything to do with the versioning.
Possible implementation:
#GetMapping(value = "/foo/produces", produces = "application/vnd.company.app-v1+json")
public FooV1 producesV1() {
return new FooV1("firstname lastname");
}
#GetMapping(value = "/foo/produces", produces = "application/vnd.company.app-v2+json")
public FooV2 producesV2() {
return new FooV2(new Name("firstname", "lastname"));
}
Changing Hostnames or using API Gateways:
Essentially, you’re moving the API from one hostname to another. You might even just call this building a new API to the same resources.
Also,you can do this using API Gateways.
I wanted to create versioned APIs and I found this article very useful:
http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http
There is a small section on "I want my API to be versioned". I found it simple and easy to understand. The crux is to use Accept field in the header to pass version information.
If the REST services require authentication before use, you could easily associate the API key/token with an API version and do the routing internally. To use a new version of the API, a new API key could be required, linked to that version.
Unfortunately, this solution only works for auth-based APIs. However, it does keep versions out of the URIs.
If you use URIs for versioning, then the version number should be in the URI of the API root, so every resource identifier can include it.
Technically a REST API does not break by URL changes (the result of the uniform interface constraint). It breaks only when the related semantics (for example an API specific RDF vocab) changes in a non backward compatible way (rare). Currently a lot of ppl do not use links for navigation (HATEOAS constraint) and vocabs to annotate their REST responses (self-descriptive message constraint) that's why their clients break.
Custom MIME types and MIME type versioning does not help, because putting the related metadata and the structure of the representation into a short string does not work. Ofc. the metadata and the structure will frequently change, and so the version number too...
So to answer your question the best way to annotate your requests and responses with vocabs (Hydra, linked data) and forget versioning or use it only by non backward compatible vocab changes (for example if you want to replace a vocab with another one).
I'd include the version as an optional value at the end of the URI. This could be a suffix like /V4 or a query parameter like you've described. You might even redirect the /V4 to the query parameter so you support both variations.
I vote up for doing this in mime type but not in URL.
But the reason is not the same as other guys.
I think the URL should be unique (excepting those redirects) for locating the unique resource.
So, if you accept /v2.0 in URLs, why it is not /ver2.0 or /v2/ or /v2.0.0? Or even -alpha and -beta? (then it totally becomes the concept of semver)
So, the version in mime type is more acceptable than the URL.