Difference between revisions of "HAppS tutorial"
ShaeErisson (talk | contribs) (add Hello World and installation instructions) |
ShaeErisson (talk | contribs) (requires HAppS 0.9.0, improve hello world) |
||
Line 1: | Line 1: | ||
− | = HAppS Tutorial = |
+ | = HAppS 0.9.0 Tutorial = |
== Installing == |
== Installing == |
||
Line 45: | Line 45: | ||
<haskell> |
<haskell> |
||
import HAppS |
import HAppS |
||
− | import HAppS.Protocols.SimpleHTTP2 |
||
-- simple HAppS app |
-- simple HAppS app |
||
+ | main = stdHTTP $ debugFilter : -- we want to see debug messages in the console |
||
− | impl = simpleHTTP |
||
− | + | noState : -- our application has no state |
|
+ | [ |
||
− | + | h () GET $ ok plain $ val "Hello" -- any GET request will return "Hello" |
|
− | ,noState -- our application has no state |
||
] |
] |
||
− | |||
− | main = stdMain $ impl :*: End |
||
</haskell> |
</haskell> |
Revision as of 21:24, 13 January 2007
HAppS 0.9.0 Tutorial
Installing
To install HAppS the following packages are needed:
- HaXml 1.13.X ( http://www.haskell.org/HaXml )
- base
- cabal (for installation)
- mtl
- network
- stm
- template-haskell ( http://www.haskell.org/th )
- with GHC 6.4 fps (http://www.cse.unsw.edu.au/~dons/fps.html)
The quick way to see what's missing is to get the darcs repository, change into that directory, and run runghc Setup.hs configure
. If you don't get an error, try runghc Setup.hs build
and then as root runghc Setup.hs install
.
Overview
The application model in HAppS is to help separate state, application logic, wire formats, protocols, and presentation layer:
State
State is just a haskell data type you define. ACID [2] Consistency enforced by Haskell's type system. ACID Durability is handled by MACID write-ahead logging and checkpointing.
Application
Incoming events are gathered in individual haskell threads and then pushed onto a single application queue for processing. The queue model gives you ACID Atomicity and Isolation and lets your app be simply a set of functions with types like:
SomeInputType -> MACID SomeOutputType
The MACID monad lets you update your state and *schedule* side-effects. To be clear, MACID is not in the IO monad so you cannot execute side effects, you can only schedule them. The framework takes care of making sure they are executed at-least-once (if they can be completed by a deadline you specify).
Wire Formats
Since your app consists of a set of functions with various haskell input and output types, somewhere you need a place to convert between those internal haskell types and external protocol event types; e.g. from URL Encoded HTTP requests to SomeInputType and from SomeOutputType to XML encoded HTTP responses.
Protocols
HAppS currently provides support for HTTP Requests/Responses and SMTP Envelopes. To be clear HAppS provides ACID Atomicity at the protocol event level. So if you write a protocol with SMTP envelopes being the arriving event type then your app will have atomicity in processing incoming SMTP envelopes. If you write a protocol with SMTP commands being the arriving event type, then your app will have atomicity at the level of individual smtp commands.
Presentation
If your application outputs XML as its wire format, HAppS provides a lot of support for using XSLT to transform it for presentation purposes. For example, you can send XML mail and HAppS will take care of applying the relevant XSLT stylesheet before it is delivered. If you output XML HTTP responses, HAppS takes care of applying the XSLT stylesheet server side for user-agents that don't support doing so on the client. The value here is that you can have designer types who know XSLT modify presentation stuff without touching your application code.
First Steps
This chapter will run you through some first simple programs written in HAppS. For other programs have a look at the directory named 'examples'.
First of all, default HAppS applications run their own webserver on port 8000, so you probably want to try out these examples at http://localhost:8000/
If you'd rather access these applications on some other port, use ./myapp --default-port=8001
obviously substituting the name of your binary for myapp.
Hello World
import HAppS
-- simple HAppS app
main = stdHTTP $ debugFilter : -- we want to see debug messages in the console
noState : -- our application has no state
[
h () GET $ ok plain $ val "Hello" -- any GET request will return "Hello"
]