abe

Easy webserver for Haxe and NodeJS built on top of Express


Keywords
nodejs, rest, webserver
License
MIT
Install
haxelib install abe 0.9.2

Documentation

abe

Join the chat at https://gitter.im/abedev/abe

Build REST apis with Haxe and nodejs.

Setup

Create a new instance of a abe.App, which listens for http traffic on a port of your choice:

import abe.App;

class Main {
  public static function main() {
    var app = new App();
    app.router.register(new RouteHandler());
    app.http(9998); // running on port 9998
  }
}

The above code registers all routes in your RouteHandler class, which could look something like this:

class RouteHandler implements abe.IRoute {
  @:get("/")
  function index()
    response.send("Hello World!");
}

Routes

abe makes super-easy getting typed parameters from user requests:

@:get("/user/:id")
function getUser(id : Int) {
  // do something with `id`
}

In this case getUser is only invoked if :id is present and it is an integer value. If those rules are not satisfied, the routing process continues to the next handler. Multiple parameters are possible as are custom filter (ex: get the user object directly as a parameter instead of the id).

By default arguments are taken from params (the route path) but with the @:args() meta you can take the arguments from: query, body, params or request. @:args can also take an array of sources when multiple sources are desired. Sources can be specified as either identifiers (no quotes) or strings.

Basic HTTP Methods

The example above used @:get to tell the function below to handle GET requests on the / route. In addition to get, you can use a variety of other HTTP methods.

@:delete("/user/:id")
function deleteUser(id : Int) {
  // delete user whose id is `id`
}

HEAD and OPTIONS

Out of the box, HEAD requests will return headers for any route you specify, and OPTIONS /some/path will return a list of methods that are accepted by the path /some/path. This happens without the need to manually specify @:head and @:options.

However, do note that making a HEAD request to a URL will run the @:get handler function, even though only the headers are returned. If you have an expensive function handling GET requests, you may wish to specify a separate @:head handler like so:

@:head("/user")
function getUserHead () {
  response.sendStatus(200).end();
}

Multiple Routes, One Handler

You can use a single route to handle a variety of types of requests (to a variety of paths, if you choose).

@:post("/user")
@:put("/user")
function createOrUpdateUser() {}

Note: you can't use the pattern above to handle the same http verb with two different paths. This is because multiple metadata with the same name will cause all but the first to be ignored.

// WILL NOT WORK
@:get("/user")
@:get("/some/other/path")
function aSingleHandler() {}

In addition to traditional HTTP verbs, you can use the special keyword all to handle all types of HTTP traffic on a route.

@:all("/foo")
function handleAllFooTraffic() {
    if (request.method.toLowerCase() == "get") {
        // do something
    } else {
        // do some other thing
    }
}

@:path

You can set a base path for your handlers by adding the @:path() to your class.

@:path("/some/")
class SomeRoute implements IRoute {
  @:get("/endpoint/")
  function getEndpoint() {
    // do something
  }
}

The handler getEndpoint responds to calls made at path /some/endpoint/.

@:use

One of the most powerful features of Express is to be able to use middlewares. abe makes using middleware super easy to use either at the handler level (methods), class level (router) or application level (abe.App).

In the first two cases you can just apply the @:use metadata with a reference to a static method satisfies the express.Middleware signature.

@:use(express.mw.BodyParser.json())

The metadata makes very easy to apply Middleware to just very specific handlers. You should take advantage of that feature instead of blindly apply Middleware globally. Still in case you want to do that you can apply the Middleware to the entire app or router.

var app = new abe.App();
app.use(express.mw.BodyParser.json());

TODO documentation:

  • class level meta

    • @:validate
    • @:filter
    • @:error
  • handler level meta

    • @:validate
    • @:filter
    • @:error