lfe-deprecated / lfest

DEPRECATED (use lfex/lanes instead)
https://github.com/lfex/lanes
Other
37 stars 1 forks source link

lfest

Build Status LFE Versions Erlang Versions Tags Downloads

Macros and functions for routing apps and services in LFE+Yaws

Introduction

REST is a party, and you know it.

The name started with more than just a party reference: the intent was for this library to be used to develop RESTful services more easily by having one's routes more clear: LFe rEpresentational State Transfer.

But the web is more than REST, so everybody gets to play. The name's staying, though.

Dependencies

This project assumes that you have rebar and [lfetool]() installed somwhere in your $PATH.

This project depends upon the following, which are automatically installed to the deps directory of this project when you run make compile:

Installation

Just add it to your rebar.config deps:


{deps, [
    ...
    {lfest, ".*", {git, "git@github.com:lfex/lfest.git", "master"}}
  ]}.

If you have created your project with lfetool, you can download lfeest with the following:

$ make get-deps

Or, you can have it download automatically when you compile:

$ make compile

Usage

Create your application/service routes with the (defroutes ...) form. Here is an example:

(include-lib "deps/lfest/include/macros.lfe")

(defroutes
  ;; top-level
  ('GET "/"
    (lfest-html-resp:ok "Welcome to the Volvo Store!"))
  ;; single order operations
  ('POST "/order"
    (create-order (lfest:get-data arg-data)))
  ('GET "/order/:id"
    (get-order id))
  ('PUT "/order/:id"
    (update-order id (lfest:get-data arg-data)))
  ('DELETE "/order/:id"
    (delete-order id))
  ;; order collection operations
  ('GET "/orders"
    (get-orders))
  ;; payment operations
  ('GET "/payment/order/:id"
    (get-payment-status id))
  ('PUT "/payment/order/:id"
    (make-payment id (lfest:get-data arg-data)))
  ;; error conditions
  ('ALLOWONLY
    ('GET 'POST 'PUT 'DELETE)
    (lfest-json-resp:method-not-allowed))
  ('NOTFOUND
    (lfest-json-resp:not-found "Bad path: invalid operation.")))

Note that this creates a routes/3 function which can then be called in the out/1 function that is required of a YAWS appmod module. For an example of this in action, see this mini REST-api.

A few important things to note here:)

Concepts

lfest needs to provide YAWS with an out/1 function. The location of this function is configured in your etc/yaws.conf file in the <appmods ...> directives (it can be repeated for supporting multiple endpoints).

YAWS will call this function with one argument: the YAWS arg record data. Since this function is the entry point for applications running under YAWS, it is responsible for determining how to process all requests.

The out/1 function in lfest-based apps calls the routes/3 function generated by the (defroutes ...) mamcro.

The route definition macro does some pretty heavy remixing of the routes defined in (defroutes ...). The route definition given in the "Usage" section above actually expands to the following LFE before being compiled to a .beam:

 #((define-function routes
     (match-lambda
       (('GET () arg-data)
        (call 'lfest-html-resp 'ok "Welcome to the Volvo Store!"))
       (('POST ("order") arg-data)
        (create-order (call 'lfest 'get-data arg-data)))
       (('GET ("order" id) arg-data) (get-order id))
       (('PUT ("order" id) arg-data)
        (update-order id (call 'lfest 'get-data arg-data)))
       (('DELETE ("order" id) arg-data) (delete-order id))
       (('GET ("orders") arg-data) (get-orders))
       (('GET ("payment" "order" id) arg-data) (get-payment-status id))
       (('PUT ("payment" "order" id) arg-data)
        (make-payment id (call 'lfest 'get-data arg-data)))
       ((method p a)
        (when
         (not
          (if (call 'erlang '=:= 'GET method)
            'true
            (if (call 'erlang '=:= 'POST method)
              'true
              (if (call 'erlang '=:= 'PUT method)
                'true
                (call 'erlang '=:= 'DELETE method))))))
        (call 'lfest-json-resp 'method-not-allowed))
       ((method path arg-data)
        (call 'lfest-json-resp 'not-found "Bad path: invalid operation."))))
   6)

When it is compiled, the routes/3 function is available for use from wherever you have defined your routes.

License

Apache Version 2 License

Copyright © 2014-2019, Duncan McGreggor oubiwann@gmail.com

[](Named page links below ...)