Farwest Demo

An overview and a demo of the Farwest project

Loïc Hoguin, Nine Nines

What is Farwest?

Erlang/OTP REST framework

HATEOAS

Standards based (whenever possible)

Built on top of cowboy_rest

Building blocks

  • Resource
  • URI and URI Templates
  • Media types
  • Operations (forms)
  • Metadata

Client libraries

One library per language/platform

Build on top of existing HTTP clients

Don't write a separate client per API

Work done so far

Discovery

  • Link HTTP header
  • Links in response bodies
  • URI Templates router, reverse routing
  • Variants
  • Skeleton Erlang/OTP client library

Generate response bodies

  • Automatic HTML generation
  • Skeleton forms
  • Automatic BED (binary Erlang data) generation

Mod:describe()

  • URI or URI Template
  • Operations
  • Operation/media type pairs (input/output)
  • Links

Configurable operations

  • HTTP method used
  • Semantics

Demo

  1. git clone https://github.com/ninenines/farwest_demo
  2. cd farwest_demo
  3. make run
  4. Open http://localhost:8080 in your browser
  5. Use curl -i http://localhost:8080

describe() → #{
    uri ⇒ "/",
    media_types ⇒ #{
        html ⇒ ["text/html"],
        bed ⇒ ["application/x-bed"]
    },
    operations ⇒ #{
        get ⇒ #{output ⇒ [html, bed]}
    }
}.
		

links(Req) →
    {ok, [
        {child, fwd_processes_r},
        {child, fwd_tables_r}
    ], Req}.
		

$ curl -I http://localhost:8080       
HTTP/1.1 200 OK
content-length: 2398
content-type: text/html
date: Mon, 27 Jan 2020 11:56:23 GMT
link: </processes>; rel="child";
    variants-06="accept=(\"text/html\" \"application/x-bed\")",
    </tables>; rel="child"; variants-06="accept=(\"text/html\")"
server: Cowboy
variant-key-06: ("text/html")
variants-06: accept=("text/html" "application/x-bed")
vary: accept
		

get(Req) →
    Info = observer_backend:sys_info(),
    Data = #{
        «"System Version"» ⇒ g(otp_release, Info),
        ...
    },
    {ok, Data, Req}.

to_representation(Req, html, Data) →
    {ok, farwest_html:from_term(Req, Data), Req};
to_representation(Req, bed, Data) →
    {ok, farwest_bed:from_term(Req, Data), Req}.
		

$ curl -I http://localhost:8080/tables
HTTP/1.1 200 OK
content-length: 7052
content-type: text/html
date: Mon, 27 Jan 2020 11:56:10 GMT
farwest-link-templates: </tables/{name}>; rel="child";
    variants-06="accept=(\"text/html\")"
link: </>; rel="parent"; variants-06="accept=
    (\"text/html\" \"application/x-bed\")"
server: Cowboy
		

Upcoming work

Improved discovery

Automatic sitemap?

Better discovery of operations

Include operations/forms in non-HTML formats

Generate response bodies

Template-based HTML generation

Automatic JSON/JSON-LD/... generation

Semantics

Schemas (schema.org or other)

Better forms using schemas

Read data and expand URI Templates

Improved client libraries

More functions

Client-side cache for Gun

Non-Erlang client libraries

Thanks

ninenines.eu