Skip to content

A REST toolkit for building highly-scalable and fault-tolerant HTTP APIs with Elixir

License

Notifications You must be signed in to change notification settings

slogsdon/placid

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Placid

Build Status Coverage Status

A REST toolkit for building highly-scalable and fault-tolerant HTTP APIs with Elixir.

Routing

defmodule Router do
  use Placid.Router

  # Define one of the versions of the API
  # with a simple version number "1"
  # or following semver "1.0.0"
  # or date of release "2014-09-06"
  version "1" do 
    # Define your routes here
    get  "/",               Handlers.V1.Pages, :index
    get  "/pages",          Handlers.V1.Pages, :create
    post "/pages",          Handlers.V1.Pages, :create
    put  "/pages/:page_id" when id == 1,
                            Handlers.V1.Pages, :update_only_one
    get  "/pages/:page_id", Handlers.V1.Pages, :show
    
    # Auto-create a full set of routes for resources
    #
    resource :users,        Handlers.V1.User
    #
    # Generates:
    #
    # get     "/users",               Handlers.V1.User, :index
    # get     "/users/new",           Handlers.V1.User, :new
    # post    "/users",               Handlers.V1.User, :create
    # get     "/users/:user_id",      Handlers.V1.User, :show
    # get     "/users/:user_id/edit", Handlers.V1.User, :edit
    # put     "/users/:user_id",      Handlers.V1.User, :update
    # patch   "/users/:user_id",      Handlers.V1.User, :patch
    # delete  "/users/:user_id",      Handlers.V1.User, :delete
    #
    # options "/users"                # "HEAD,GET,POST"
    # options "/users/new"            # "HEAD,GET"
    # options "/users/:_user_id"      # "HEAD,GET,PUT,PATCH,DELETE"
    # options "/users/:_user_id/edit" # "HEAD,GET"
  end

  # An updated version of the AP
  version "2" do 
    get  "/",               Handlers.V2.Pages, :index
    post "/pages",          Handlers.V2.Pages, :create
    get  "/pages/:page_id", Handlers.V2.Pages, :show
    put  "/pages/:page_id", Handlers.V2.Pages, :update
    
    resource :users,        Handlers.V2.User
    resource :groups,       Handlers.V2.Group
  end
end

get, post, put, patch, delete, options, and any are already built-in as described. resource exists but will need modifications to create everything as noted.

version will need to be created outright. Will allow requests to contained endpoints when version exists in either Accepts header or URL (which ever is defined in app config).

Extra routes will need to be added for *.json, *.xml, etc. requests for optionally specifying desired content type without the use of the Accepts header.

Handlers

defmodule Handlers.V2.Pages do
  use Placid.Handler

  @doc """
  List all available pages
  """
  def index(conn, []) do
    # Somehow get our content
    pages = Queries.Page.all
    render conn, pages
  end

  @doc """
  Show an individual page
  """
  def show(conn, args) do
    result = case Integer.parse args["page_id"] do
        :error -> 
          %Error{ id: "no_page_id",
                  message: "A valid page_id is requried." }
        {i, _} ->
          Queries.Page.get i
      end

    render conn, result
  end

  @doc """
  Create a new page
  """
  def create(conn, args) do
    render conn, Queries.Page.create args, status: :created
  end

  @doc """
  Update an individual page
  """
  def update(conn, args) do
    result = case Integer.parse args["page_id"] do
        :error -> 
          %Error{ id: "no_page_id",
                  message: "A valid page_id is requried." }
        {i, _} ->
          Queries.Page.update i, args
      end

    render conn, result
  end
end

Actions in handler modules are responsible for handling a request once it has been routed. These actions typically generate a response, whether that be an error, a result, or a result set, so that it can be rendered to the client with the correct content type further up the stack.

Rendering

Render layer serializes/encodes data based on the requested content type unless overridden for whatever reason in the response stack.

Parsers

Parsing request bodies from their content type to Elixir terms allows the handler actions to easily use that data in responding to the client. There should be one parser for each supported response content type, with an additional parser for form encoded data.

TODO

  • Compatibility with web frameworks via umbrella projects.
    • Would be nice to offer tight integration when available, e.g. Phoenix.Topic notifications
  • Respects HTTP specifications (7230, 7231, 7232, 7233, 7234, 7235)
  • Foundations (link)
    • Require TLS (link)
    • Version with Accepts header (link)
    • Support caching with Etags (link)
    • Trace requests with Request-Ids (link)
    • Paginate with ranges (link)
  • Requests (link)
    • Return appropriate status codes (link)
    • Provide full resources where available (link)
    • Accept serialized JSON in request bodies (link)
    • Use consistent path formats (link)
    • Downcase paths and attributes (link)
    • Support non-id dereferencing for convenience (link)
    • Minimize path nesting (link)
  • Responses (link)
    • Provide resource (UU)IDs (link)
    • Provide standard timestamps (link)
    • Use UTC times formatted in ISO8601 (link)
    • Nest foreign key relations (link)
    • Generate structured errors (link)
    • Show rate limit status (link)
    • Keep JSON minified in all responses (link)
  • Artifacts (link)
    • Provide machine-readable JSON schema (link)
    • Provide human-readable docs (link)
    • Provide executable examples (link)
    • Describe stability (link)

This list comes primarily from the HTTP API Design Guide by @interagent and friends but will be updated to fit the needs of the project.

License

Placid is released under the MIT License.

See LICENSE for details.

About

A REST toolkit for building highly-scalable and fault-tolerant HTTP APIs with Elixir

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages