Throughout the book, you’ve been preparing for this moment: you know how to save information about clients and products, and you know a couple of algorithms to mine that data for interesting patterns. Now it’s time to create an interface for clients to make purchases. This data will be the input to K-means and Apriori.
The most interoperable and arguably the most widely used way to create an interface for such an application is to write a web application. Your clients will be expecting to just enter a web address in the browser and get the list of products, put them in a virtual cart, and pay at the end. For that reason, this chapter will focus on building web applications using Haskell.
The development of such an application is divided into two parts. In the first part is the back end, which includes a server that will listen for HTTP requests and return and update information about clients, products, and purchases. For this task, you will reuse much of the knowledge from previous chapters and also learn about Spock, a minimalistic web framework for Haskell, and digestive-functors, a library for handling forms using applicative style.
Then, the focus will turn to the front end, that is, the code that ultimately runs in the browsers of your clients, making the correct requests to the back end. Usually this part would be written in JavaScript; but, as you will see, it’s possible to reuse most of your Haskell knowledge if you use a language such as Elm. This will lead to consider how to manage a graphical stateful application in functional style.
Haskell Web Ecosystem
Web applications are becoming the standard way to interact with users. The benefits of this approach are many; you don’t have to create a different executable for each system from which your client may access your application (although you still need to consider interoperability issues between browsers), and you don’t need users to download or execute any binary code. Everything runs smoothly inside the browser.
If you look at Hackage, you can see an increasing number of packages that deal with web applications. These packages range from being traditional, using patterns similar to frameworks in other languages, to experimental ways of composing an application (in this last group, Functional Reactive Programming [FRP] libraries are becoming popular).
Given the number of possibilities, I will give you an overview of the most important libraries you can use for developing a web application, as I did for accessing a database management system. Of course, this chapter cannot possibly cover everything related to web applications in Haskell. It will focus on a handful of libraries: Spock, blaze-html, Hamlet, and digestive-functors are the chosen ones for the back end. For the front end, I’ll introduce a language different from Haskell but based on it: Elm.
Web Frameworks
A web framework is a library or set of libraries intended to be used when developing a web application, covering all possible technological requirements. These requirements usually include a routing system (for linking a URL to a specific piece of code to be executed when this URL is to be served), a templating system (for generating the final HTML output), several kinds of caches, database access, and authentication through different protocols.
In other languages, a web framework is usually a monolithic library that provides everything in one place. However, Haskell developers usually strive for more modularity, and the most common pattern in Hackage is a set of packages that are developed together that share part of their name (e.g., all the packages starting with yesod) but do not require each other in order to be fully functional. This means you can build your web application by pulling different pieces from different projects. Even though using a single framework gives you the most comfortable experience, using several of them does not imply that the resulting code will be messy at all. Indeed, the Time Machine Store presented in this chapter will use routing, templating, and form-handling libraries from different projects all at once.
Happstack is one of the most veteran frameworks in the wild. One of the most prominent uses of Happstack is clckwrks, a content management system. The main package, happstack-server, provides access to almost all the information about HTTP requests and responses, including compression, cookies, or authentication. On top of that, a Happstack user would usually add happstack-foundation as a dependency, which adds a lot of packages that work together well in a Happstack environment. Most often data gets handled via the acid-state package, routing is done with the web-routes package, and form handling takes place via reform. There’s no preferred templating engine although HSP (Haskell Server Pages), Heist, and Hamlet are listed in the documentation. web-routes and reform are based on the same principles that will be discussed in relation to Spock. The ideas behind HSP are similar to other templating languages such as JavaServer Pages (JSP): you write the HTML you want to be generated, decorated with small chunks of code written in Haskell.
Most of the other frameworks do not include their own server. They are built upon a generic interface called Web Application Interface (WAI) . In principle, you could use any server that understands this interface to run your code (as you can use many servlet engines to run Java web applications). But in practice, only the Warp server is used in production. For that reason, most of the other frameworks provide direct access to running a web application using Warp.
Snap is the name of one of those libraries built upon WAI. There are two main features in the design of Snap. The first one is the focus on giving the developers tools for writing modular components that are later composed (called snaplets ), instead of aiming for monolithic applications. The second one is the use of Heist as their choice of templating library, which uses plain HTML in combination with special tags to request information from other layers of the application.
A third choice is Yesod. The main goal of Yesod developers is to make everything as type-safe as possible. The Persistent library that has already been discussed is developed as part of this framework. If you remember, Persistent schemas were described using a small language that was parsed using quasiquotation and Template Haskell. Yesod brings the same ideas to other parts of the web application; routing and templating are specified using those blocks. For templating, the Shakespeare library can output each common language on the Web with the use of several quasiquoters: Hamlet for HTML documents (which will be discussed in this chapter), Cassius and Lucius for style sheets, and Julius for JavaScript code.
Servant is younger than the other frameworks but has a lot of potential. Its goal is also to make Haskell type-safety guarantees work for us. However, the approach is completely different to Yesod’s. Most parts of the application are described using a type, and this type is later used to automatically generate routing, templating, or marshaling to JSON. Due to the more complex nature of the type-level part of a Servant application, to use it proficiently you need to master the techniques described in the next chapter.
The focus in this chapter for routing and general application scaffolding will be Spock,1 a minimalistic web framework with focus on strong types. You can think of it as the Haskell version of Ruby’s Sinatra or Python’s Flask. The main feature it provides is an easy description of routes and an easy way to plug in templating libraries (you will see how to use both blaze-html and Hamlet with it). Being so minimalistic, it doesn’t require many different concepts to be understood in order to start using it. This makes it a perfect point to start looking at Haskell web libraries and later move into more complete ones when you require their extra functionality.
One of the points where Spock is weaker is when handling the information that clients give through forms. The library digestive-functors is one of the most popular libraries to bridge this gap (it’s even the preferred way to do so in Snap) and the choice for this chapter. Remember about the aeson library for handling JSON that was introduced in Chapter 10. digestive-functors also builds upon the applicative style to define forms and validation.
For the previously mentioned packages, there is a lot of documentation, even in the form of tutorials and books, so I suggest you look at them to see the differences for yourself. For an updated list of Haskell web frameworks (including the ones mentioned above and many others) and pointers to their web sites, you can check out the Haskell wiki at wiki.haskell.org/Web/Frameworks .
Compilation to JavaScript
Up to now, the frameworks I have discussed deal with the back end (also known as the server side) of the application. They allow you to generate HTML pages that will be the part that the user will ultimately see. Unfortunately, HTML itself is not able to describe all kinds of behaviors that are expected in a dynamic web page, and developers need to resort to JavaScript. Every modern browser includes a JavaScript interpreter that exposes an enormous amount of functionality to the user and allows for creating sophisticated applications (think of the various web pages that show interactive maps).
The problem is that you may not want to code your entire front end (or client side) in JavaScript. JavaScript is a mixed imperative and prototype-oriented language. Even though it integrates some features from the functional paradigm, its syntax and, more importantly, its concepts are very different from Haskell’s. Using the same language for both the back end and the front end reduces the mental effort you need to make when working on both parts at the same time, and it increases the possibilities of sharing code between the parts.
However, making the browsers support a new language is just an illusion. JavaScript is the language where all the efforts are focused. For that reason, many compilers have included the option to generate JavaScript as output apart from binary code. Then, you can use your preferred programming language to write dynamic web pages and still retain the ubiquity of support that JavaScript has on browsers. Furthermore, these days, the speed and quality of JavaScript implementations are quite impressive. The functional community as a whole has worked in that direction, and there are several Haskell-inspired languages that can be compiled into JavaScript.
Some projects such as GHCJS, WebGHC, and Haste modify the GHC compiler itself to output this alternative representation. These projects have different areas of focus, from allowing seamless execution of any application that can be compiled by GHC into a web environment, replicating the entire runtime, to trying to balance full compatibility with GHC and better interoperability with other JavaScript codes. Unfortunately, it seems that these projects have not caught upon Haskell practitioners, and at the moment of writing using and developing with them is not as simple as using GHC.
An alternative approach is to create a completely new language, but strongly based on the syntax and concepts of Haskell. There are two main projects in this area. PureScript is the closest language to Haskell, and shares with it a powerful type system. The main difference is that code is not executed lazily, it uses the most common execution model inherited from JavaScript instead. The other side of the spectrum is covered by Elm, which removes some Haskell’s features (like type classes) in order to provide a simpler language. But we still have higher-order functions, pattern matching, and many of the defining features of Haskell. Elm is the focus of our section about front end.
Like in the case of web frameworks, many other languages and packages provide support for compiling into JavaScript. You can get an up-to-date list with pointers on documentation at wiki.haskell.org/The_JavaScript_Problem .
RESTful Structure
Before starting with the coding, I will introduce some of the general patterns in the design of the application, which are based on the Representational State Transfer (REST) principles. Many of these concepts are directly encoded by the combinators that Spock provides and are visible in many other web frameworks, both inside and outside the Haskell world.
The core idea is that the web application provides access to a set of resources, which can be queried or modified. The information of a client or a product is an example of resources in the Time Machine Store. Each of these resources is accessed through a unique identifier, which in a web application is a URL. For example, /clients could be the identifier of the list of all clients, and /product/3 may identify the information of the product whose identifier in the database is the number 3.
Given that URLs are central to knowing which data must be queried or affected by a request, the web framework of choice should include good support for specifying URL patterns and point to the right code to execute. Each of these patterns is called a route . For example, in Spock you can describe the route for products as /product/<var>, meaning that when any URL starting with /product/ is found, that code is executed, and the rest of the URL is captured in a variable.
For each resource, an application can have several request methods , each of them being a particular action over the resource. For web applications, which are the focus of this chapter, the most used request methods are GET, which retrieves a particular object or lists the elements in a collection; POST, which is used to create a new element inside a specific resource; PUT, which replaces the information of an entire resource with new information coming with the request; and DELETE, which erases the resource from the system. The REST architecture style imposes several constraints on how each method should behave (e.g., GET should not modify the resource at all). You can read about it in many books about this topic, so I won’t delve into details here.
Finally, for each supported combination of resource identifier and request method, the application should give a response using standard formats. When using REST over HTTP, this means using HTTP status codes (e.g., returning a 404 error when some resource is not found) and encoding the queried information using HTML, XML, or JSON. Furthermore, the consumer can specify a list of supported response types, and the server should try to satisfy that requirement .
Back End with Spock
In this section, you will develop the back end of the Time Machine Store. Because of space constraints, I will focus primarily on querying and updating information about products. Support for clients and purchases is left as a good exercise to put together much of the knowledge you’ve acquired up to this point.
Simple Skeleton
The first thing to do is to set up a project with an executable stanza that will start the server, adding Spock as a dependency.2 You’ve already gone through these steps in the first four chapters. Now repeat them in Exercise 12-1 to create the basis for the store. Remember that exercise solutions are included with this book’s example download from the Apress.com catalog page.
Exercise 12-1. Setting up the Project
Create a new Cabal package, either using Cabal or Stack, named chapter12. This package should contain a stanza that will generate the time-machine-store executable. Add Spock as a dependency of the executable.
The entry point of the application, the main function, starts your Spock application at port 3000. In addition to the port number, the runSpock function needs some configuration parameters, and more importantly, a description of your routes, which in this case we define in app. Right now, there’s only a route, /about, which can be accessed through the GET request method. This route is defined using the name of the method in lowercase letters (get), a pattern which the URL must follow, and finally the handler, which is the code to be executed.
Note
Routes are defined via a value of type Text. The previous code uses the OverloadedStrings extension to write them as string literals.
The result of a request in Spock can be any Text value, which is the data that will be sent over the wire. However, if the data you are returning must be processed as HTML, it’s customary to define the value of some of the response headers. But instead of defining it by hand, Spock provides the html helper function, which sets those headers to the appropriate values and then returns the content.
You can check that your web application works by building the package at the command line and calling it. Then point your browser to http://localhost:3000/about to run the corresponding handler and show the result on your screen.
One of the most important things to notice is that when the URL is not found, you should set the response status to the corresponding number (in this case, the well-known 404). This is done by calling setStatus , which takes as a parameter one of the codes defined in the Network.HTTP.Types module (this module is not defined inside the package Spock but on http-types, which you should include as an extra dependency).
Caution
Spock checks which route to apply in the same order as they appear in the code. A hookAnyAll route handles every possible URL. Any route after that one will never be executed. For that reason, you must always write the hookAnyAll route as the last one in the description of your application.
Showing Products from the Database
Now let’s move on to the main task in this section: showing information about products. The access to that data will be via the Persistent library (thus, you should include persistent, persistent-template, and persistent-sqlite as dependencies) using the same schema from Chapter 11. In the examples, I will assume that the database schema is described in the module Chapter12.Database.
There are two changes to be done to the main function to make the database available to the handlers. First, you should make sure the schema described via Persistent coincides with the actual database schema. As you know, this is achieved via a migration, which should be the first thing to appear in main.
The creation of the connection pool is done with the usual withSqlitePool function. Note that we do not use the pool yet, instead we initialize the configuration with it by using PCPool, in contrast to our previous use of PCNoDatabase. The type of app also needs to change to reflect that the routes may access a database of type SqlBackend. At any point in the handler you can request a connection via the runQuery method; Spock manages the pool for you.
The rest of the code is a straightforward access to the database as explained in Chapter 11 for accessing a value via its identifier and composing the returned HTML value. The code uses record wildcards to bind variables from the Product record easily. When a product identifier is not found, the status code of the response is set to 404 using the same approach as for “not found” routes in the previous section.
The code shown previously is quite short and simple, except for one part: the construction of the resulting HTML page, which is done via simple string concatenation. After seeing how many checks a Haskell compiler can do for you in so many realms, you should ask whether there’s some tool for helping writing HTML code, making sure you close all tags, using indentation to discern the document structure, and so on. The answer is positive: I’m going to show you two different libraries that take different paths for this task.
The first option is the blaze-html package . The idea is that each HTML element is represented by a function whose final parameter is a monadic value representing all those tags nested inside. This way, you can write nested do blocks to simulate the document structure in your Haskell code. The other main combinator is (!), which allows you to include HTML attributes for each element.
Hamlet templates use opening tags in the same way as HTML. However, indentation is the syntactic element marking the nesting structure, so closing tags are not needed, as you can see in the previous example. At any moment you can “escape” to the Haskell world via #{ }, and the result of the expression inside the brackets will be printed safely at that point.
The hamlet function allows you to use type-safe URLs . The idea is to define all possible routes in your web application using an ADT. Each of the constructors will describe a URL pattern along with the set of parameters. Then, instead of building your HTML links by hand, you specify one of these constructors every time you need a link. The web-routes generates most of the boilerplate code needed to use this feature.
The ihamlet function adds internationalization support to the mix. You can create a general document structure for your templates and then include different messages for each language that your web application supports.
Finally, for each of these functions, Hamlet provides a corresponding function ending in File (shamletFile, hamletFile, ihamletFile) that reads the template for an external file. In that way, you can separate the view of your data from the logic in the server.
Exercise 12-2 asks you to implement the same functionality as you’ve done for products, but now you can do this for clients of the Time Machine Store.
Exercise 12-2. Querying About Clients
Include the new routes /clients, /client/:clientId, and /json/client/:clientId that return information about all clients and a particular client in HTML and JSON formats. Use any of the presented templating systems for generating the HTML output.
Inserting New Products Using Forms
Right now, you have tools only for writing routes that use information from the URL to respond. But when a user is expected to give some data interactively, the interface should present a form, and the web application should take as input the information from that form. How to do this in an elegant and composable way will be the main topic of this section.
Before continuing, it should be noted that Spock provides a set of param* functions to get the value of fields in a form. By default, param looks in both the POST and GET variables, but more concrete versions are provided. The problem with using param the entire time is that the parsing and visualization of forms becomes stripped between different handlers. Furthermore, you need to manually convert from Text to the required format, and deal with erroneous input. You should aim instead to have a centralized description of each form in your web application that can be reused between different handlers (e.g., your product form may be used both for creating a new one and for updating the information of an existing one).
The package you will use in this web application for form handling is called digestive-functors . One interesting feature of this library is its use of the applicative style, which gives forms the same flavor as JSON handling with aeson, which has been already discussed in this book. The digestive-functors package also separates the description of the data and validation for building a value from the way in which that form should be visualized, giving a modular approach to form handling.
Caution
Both aeson and digestive-functors contain a function called (.:). Be aware of this fact; you will need to qualify at least one of them if you’re using the two modules in the same source file.
Once you have the description of your form, it’s time to define how it will be seen by the user. The code you need to create should take a view of the form (in other words, a definition of the form plus values for each of the fields) and return the HTML output. There are packages for integrating forms with almost any of the templating systems I introduced at the beginning of the chapter. In this section, I will use blaze-html as an example, so you need to add digestive-functors-blaze as a dependency.
Note
getForm returns a View String value (since the definition of productForm had type Form String m Product), whereas productView needs a View H.Html value. You can move from the former to the latter by mapping H.toHtml on every field, as the previous code does. The idea behind this conversion is that you should map the errors in the form from the String type to an HTML representation.
This section serves as a good introduction to building REST web applications in Haskell, in particular using Spock. To fix the concepts in your mind, you should try to complete the back end of the application as Exercise 12-3 suggests. Afterward, if you are interested in web applications in Haskell, you can dive more deeply into Spock (e.g., how to deal with sessions or cookies) or learn about any of the other frameworks that were mentioned earlier in the section “Web Frameworks.”
Exercise 12-3. Registering Clients
Create a new handler for registering clients at route /register. As in the case of products, you need to add handlers for both the GET and POST request methods.
Hint: You may want to read the documentation of the choice combinator in digestive-functors to learn how to build a drop-down list with possible countries in your HTML form.
Front End with Elm
This section is devoted to creating a rich front end for the Time Machine Store web application using Elm. As in the previous section, space constraints limit the discussion to a shallow introduction to the Elm ecosystem and its use to show some products using the back end described above.
Getting Elm in your System
Elm website, located at elm-lang.org , has at the moment of writing a big Install button in its main page. In Windows and Mac it is recommended to use the installer, which also set ups the correct paths in the system; in Linux this set up needs to be done manually.
If you have npm (Node.JS Package Manager) already in your system, you can just run npm install elm --global to get the binaries in the right place. npm is quite popular in the JavaScript world.
In this section, we are going to use one of Elm’s facilities for rapid application development: elm reactor. Usually, in order to use one of these JavaScript-based languages, you need to create an accompanying web page, compile the code to JavaScript, and then call if from the page. Each step is easy, but it creates quite some overhead for a few simple examples. In contrast, using reactor you just need to initialize a folder as a project, and then point your browser directly to an Elm source file. The code is then compiled and executed, without any further configuration.
The simplest version of the Elm Architecture, depicted in Figure 12-1, requires us to provide three components: the model, that is, which is the data our application saves; the update function, which describes how the model is update in response to event such as user input; and the view, which specifies how to render the data in the model as HTML. In turn, the model is defined in two parts: first of all you need to declare a data type which defines all the possible states of the application, and in addition you have to specify the initial state.
![../images/316945_2_En_12_Chapter/316945_2_En_12_Fig1_HTML.png](http://imgdetail.ebookreading.net/software_development/2/9781484244807/9781484244807__practical-haskell-a__9781484244807__images__316945_2_En_12_Chapter__316945_2_En_12_Fig1_HTML.png)
Simple Elm Architecture
In this case, the model is simply a string. In the code, though, we use a kind of types which is not available in Haskell’s type system, namely records or row. Our Model type is made up of one single piece of data, which is available under the identifier currentName. If you look closely at the view function below, you can see that we use model.currentName to access the information. These types, inherited from JavaScript, provide a simple way to gather information without the overhead of using constructors everywhere. The init function specifies the initial value for this field; feel free to use your own name there.
The view function describes how to turn a value of the Model type into an HTML document. There is nothing surprising: Elm’s approach to markup follows similar ideas as the blaze-html package we have discussed above.
The first thing I have done is enlarging the model to incorporate both the current name and the information which is currently saved in a textbox. One possibility would have been to keep the greeting completely in sync with the value of the textbox, but in this example, the user must click a Greet me! button explicitly. This way we look at a bit more complex workflow.
The next place to look at is the definition of view. In addition to the previous line of text, we now have an input element (corresponding to the textbox) and a button element. In both cases, we set up handlers for possible events: in the case of the textbox when the text changes, and in the case of the button whenever it is clicked. In contrast to many graphical interface toolkits, these handlers do not specify functions to run, but rather messages to be sent.
This leads us to the definition of the Msg type, which declares all possible messages that the application can handle. In our case, they correspond closely to the user interface elements, but in general, they might describe any possible event in the application, like a change in the data. The update function is responsible for taking each of the messages and specifying how they affect the underlying model of the application. In this case, the TextboxChanged messages updated the corresponding field in the model, and the MakeCurrent message moves the name from the temporary to definite storage. In turn, this causes the view function to run, leading to visible output for the user.
The right way to think about the Elm Architecture is like a state machine. Each constructor in the Model type defines one state in the application, along with any additional data that it might need. Messages move the application to different states. Apart from this core, we need a way to reflect the changes in the data to the outside; this is the role of the view function. This architecture is a very common way to define user interfaces in the functional world,3 and it has been slowly gaining traction out of this niche. Popular projects like React use very similar ideas.
Retrieving Products
The architecture formed by a model, an update function, and a view works well if your application is self-sufficient. That is, if all the data is contained in the initial state or a product of the user input. But this is not true for many (or even almost all) web applications: the data is not present at the beginning of the application but obtained later by making calls to remote servers (usually your application back end). This behavior requires an extension to the Elm Architecture.
The core idea to model operations which are out of the control of the application, and might be asynchronous, is to use commands . A command represents any operation that we want to request from the outside world – what exactly depends on the library you are using. Once the command finishes working, and has a final value, a message is sent to the application. This message is handled in the same fashion that any user input: by calling the update function which performs any required changes to the model, and then updating the view.
In the code above you can see that Browser.element requires subscriptions in addition to the three components I have been discussed throughout this chapter. By subscribing you can get a stream of events in your application; in contrast to a command, which gives you back only one message. The archetypal example of a subscription is time: you can request to get a tick every n seconds, and the system sends the corresponding message every time the wait is over. In this example, we do not want to subscribe to anything, so we initialize the corresponding field to a function which always returns Sub.none, in the same way that our initial style requests no command using Cmd.none.
The missing piece is the view function to turn the model into HTML elements. Exercise 12-4 asks you to implement this function.
Exercise 12-4. A View for Products
Implement the missing view function in the application above. Remember that you need to have at least one textbox whose changes lead to TextboxChanged messages, and a button that raises a Load message when clicked.
Elm is a very productive language, even though some Haskell features are missing from the language. In fact, its designers argue that a simpler language makes it easier to introduce functional programming in an area of programming – web applications – where only JavaScript has been traditionally used.
Same Origin Policy
If you’re executing all these examples in a local environment, your web page may not work at all. In that case, you’ll have been surely bitten by the Same Origin Policy. This policy, implemented in every browser in the wild, forbids a page in a domain to obtain information from other domains. In this case, a local page may not send information to a web application in localhost:3000, which we have used for our Spock back end.
The easiest solution is to add a header to allow communication from any domain in the Scotty code. This is done by calling setHeader "Access-Control-Allow-Origin" "*" in the handler of the JSON route. In this way, you notify your browser that the server admits calls from everywhere.
Having said that, it’s obvious that you shouldn’t add that header in every web application you create because you may be exposing information to other domains. The best solution is to sever both the back end and front end from the same domain. Alternatively, you can include a restrictive list of allowed clients in the Access-Control-Allow-Origin header.
Summary
You learned about the many libraries that the Haskell ecosystem provides for each feature required in a web application: routing, templating, form handling, and so on.
The chapter focused on the development of the Time Machine Store following the principles of the REST architectural style.
Spock was introduced as a minimalistic web framework, and you saw how to create handlers for different routes and request methods.
Two templating systems were discussed: blaze-html, which provide a set of combinators for composing HTML documents, and Hamlet, which uses quasiquotation to embed a markup language inside Haskell code.
For handling input from the user, you learned about the digestive-functors library.
Finally, Elm was introduced as a way to program rich front-end web pages using a Haskell-inspired language, and you saw a small demo for obtaining remote information.