NAV

Introduction

Web Development Using a Distributed, Concurrent Lisp

About Dragon

For a long time, LFE didn’t have a web framework. Anyone doing web just rolled whatever they needed using YAWS or Cowboy and libraries from the BEAM ecosystem. This is a pretty standard approach in the Erlang world, and arguably a habit that could do more to embrace new users.

With the massive growth of the Elixir community, many of whom have backgrounds in Ruby, Python, etc., the expectations have changed around providing developers with go-to solutions. In particular, the Elixir community has produced the extremely popular Phoenix Framework for web development. Members of the LFE community have been singing its praises and asking for something similar.

In the world of mythology, a natural and amicable complement to the Phoenix is the Dragon. The LFE web development project chose this name to deliberately emphasize this. Due to the fact that both Elixir and LFE are BEAM languages, one can use the Phoenix framework with LFE. However, some LFE devs would prefer to not only use a web framework, but hack on one as well – doing both in LFE. Dragon is for them. It is this level of flexibility that we see the frameworks complementing each other.

Dragon’s philosophy is oriented towards collections of libraries. This approach derives from that of the lmug collection of libraries (lmug, 2014) which in turn was inspired by Clojure’s take on WSGI: Ring. In this same spirit, Dragon makes no demands on how you do things – it simply offers a collection of libraries, example usage, deployment advice, and lots of Lisp.

For a tongue-in-cheek overview of the Dragon philosophy, see the Dragon Manifesto.

What You Get

Version 0 of Dragon ships with YAWS, lfest (routes), exemplar (S-expression-based XML and HTML), mnemosyne (Nosql) , ljson, and logjam. As such, you have all the tools necessary to build simple web applications.

Components

Some of the libraries mentioned above touch upon the conceptual components of a Dragon application. These are as follows:

How each of things gets done is up to the developer. We do provide examples and may eventually offer some best practices guides, but we don’t impose implementation details around these. If you want to include messaging, you can either use the built-in capabilities of Erlang and LFE processes, or you can add RabbitMQ as a dependency for your system. Your data access code, your “business logic”, and your “display” or “rendering logic” should all be loosely coupled, but you may do this in whatever way you see fit.

What’s Coming

In future releases of Dragon, we will

Stay tuned!

Documentation

The Dragon documentation provided here is currently in progress. The content is organized along the following lines:

This will eventually mature into sections with a user guide, more tutorials, operators manual (e.g., deployment guides) and the like.

Doc Conventions

We use styled call-outs to provide immediate visual cues about the nature of the information being shared.

These are as follows:

Getting Started

Overview

This section lists the software and details the concepts needed in order to start using Dragon. Note that in this 0.0 “release” of Dragon, you will essentially be using a collection of components most actively used by LFE projects that create web sites or web services. These are not currently “branded” as being part of the Dragon project – that will come in the next release of Dragon.

Prerequisites

To use Dragon, you will need to have the following installed and running (if applicable) on your system:

Project Structure

A minimal Dragon project layout:

├── priv
│   ├── etc
│   │   └── yaws.conf
│   └── www
│       ├── <static files & dirs>
│       └── favicon.ico
├── rebar.config
└── src
    ├── yourapp.app.src
    ├── yourapp.lfe
    ├── app-content.lfe
    └── app-routes.lfe

A minimal Dragon project consists of the following:

Project Configuration

rebar.config

Dragon project configuration file:

{deps, [
   {lfe, {git, "https://github.com/rvirding/lfe.git",
         {branch, "develop"}}},
   {yaws, {git, "https://github.com/oubiwann/yaws.git",
          {branch, "rebar3-support"}}},
   {lfest, {git, "https://github.com/lfex/lfest.git",
           {tag, "0.3.0"}}},
   {exemplar, {git, "https://github.com/lfex/exemplar.git",
              {tag, "0.4.0"}}}
  ]}.

{plugins, [
   {'lfe-compile', {git, "https://github.com/lfe-rebar3/compile.git",
                   {tag, "0.4.0"}}}
  ]}.

{provider_hooks, [{pre, [{compile, {lfe, compile}}]}]}.

LFE projects tend to use rebar3 to manage dependencies and builds, and Dragon is no exception. A pretty simple project configuration is demonstrated to the right.

This project configuration highlights the major dependencies (some of which have other dependencies), all of which will be automatically downloaded for you by rebar3. The dependencies and what they do are as follows:

Erlang app.src

Dragon app.src example:

%% -*- erlang -*-
{application, yourapp,
 [
  {description, "Your Super-Great LFE+YAWS Web Application"},
  {vsn, "0.1.0"},
  {modules, [yourapp]},
  {registered, []},
  {applications, [kernel, stdlib]},
  {included_applications, []},
  {mod, {}},
  {env, []}
 ]
}.

All Erlang and LFE projects need to define an app.src file. Dragon expects this file to be in the src directory for your project (it will get “compiled” to the project’s ebin directory). Here is an example yourapp.app.src file:

yaws.conf

YAWS configuration file:

logdir = log

<server localhost>
        port = 5099
        listen = 0.0.0.0
        appmods = </, yourapp exclude_paths favicon.ico>
        docroot = priv/www
</server>

Note that if the log directory configured above doesn’t exist, you will need to create it:

$ mkdir log

In addition to the project as a whole, you will need to configure YAWS to run your project. This is done with the priv/etc/yaws.conf file, as shown to the right.

The most important configuration directive there is the appmods one. This is where we tell YAWS what the entrypoint for our application is. In this case, it is the module yourapp. YAWS will look in the module listed here and call its out/1 function.

In this case, the output of yourapp:out/1 will be served at the path / but any request to /favicon.ico will be ignored; that will instead be served from the docroot at priv/www. If there were other static resources (such as image, javascript, or style sheet directories) that we wanted YAWS to ignore, we would list those with favicon.ico after the exclude_paths option.

Application Code

Entry Point

Dragon entry point module:

(defmodule yourapp
  (export all))

(defun out (arg-data)
  "This is called by YAWS when the requested URL matches the URL specified in
  the YAWS config (see ./priv/etc/yaws.conf) with the 'appmods' directive for
  the virtual host in question.

  In particular, this function is intended to handle all traffic for this
  app."
  (lfest:out-helper arg-data #'app-routes:routes/3))

We mentioned the application entry point above. To the right is an example of what that would look like.

As you can see, there’s not much to this file. In general, you may find that to be the case, even with fairly complicated web apps – much of the logic will very likely be organized into separate modules. Any top-level app-related code, though, will do well to live in this module.

The out/1 function passes our app routes to the module where our routes are defined: app-routes:routes/3. Let’s take a look at that module next.

Routes

(defmodule app-routes
  (export all))

(include-lib "lfest/include/lfest-routes.lfe")

(defroutes
  ('GET "/"
    (lfest-html-resp:ok
      (app-content:page "Page Title" "Hello, World!"))))

Creating Content

TBD

Running the Server

TBD

Further Reading

If you would like to see a complete example of a minimal LFE+YAWS web application, be sure to check out this project:

After a git clone, check directory to lfeyawsmini and run make run. This will download all the deps, build them, and then run the server which will be accessible at http://localhost:5099.

A slightly more interesting LFE+YAWS web application is here:

This demo application uses Bootstrap and a litle bit of jquery to build a themed site with dynamically generated content.

That project is the subject of the Dragon Tutorial

The Dragon Tutorial

The tutorial differs from the “Getting Started” guide in that it explores more of Dragon, its dependencies, and introduces more of its capabilities.

Overview

TBD

Prerequisites

TBD

Project Configuration

TBD

YAWS Configuration

TBD

Application Routes

TBD

Creating Content

TBD

Running the Server

TBD

Further Reading

TBD

The Dragon Manifesto

TBD!

Previous Versions

Documentation is available for all previous releases:

License

Copyright © 2016 LFE Dragon Team

Distributed under the Apache License, Version 2.0.