Giter VIP home page Giter VIP logo

hyperl's Introduction

Hyperl

Hypermedia API middleware for Elli. This is proof-of-concept quality. It's bug ridden and everything is very much subject to change. I hope you'll weigh in if you have opinions.

Concept

HTTP middleware should isolate HTTP implementation details from the application logic. Elli has excellent middleware support that should allow for all HTTP concerns to be handled without resource processes having to provide specialized responses.

This particular approach expects you to provide metadata that defines how to render a resource, its actions and any embedded children.

This middleware has a ways to go. See the To Do section for more details.

Including In Your Project

Add the following to {deps, []} in your rebar.config:

{hyperl, "",
	{git, "git://github.com/arobson/hyperl",
	{branch, "master"} } }

Wiring Into Elli

The following block demonstrates the entire setup (including the previous supervisor setup).

init([]) ->
	RestartStrategy = one_for_one,
	MaxRestarts = 3,
	MaxSecondsBetweenRestarts = 60,
	SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts},

	%% the list of resource modules get passed to configure
	Hyperl = hyperl:configure([parent]), 

	MWConfig = [{mods, [
		Hyperl %% just place this in the list of middleware modules
	]}],
	
	ElliOpts = [{callback, elli_middleware}, {port, 8090}, {callback_args, MWConfig}],
	Elli = {elli,
		{elli, start_link, [ElliOpts]},
		permanent, 1000, worker, [elli]
	}

	
	Hyperl = {hyperl_sup,
		{hyperl_sup, start_link, [MetadataModules]}, 
		permanent, 1000, supervisor, [hyperl_sup]
	},
	{ok, {SupFlags, [Elli, Hyperl]}}.

Example Resource Action

The resource callback module should provide a function to handle every action specified in the metada. The Data parameter is the body of the request (or [] if no body is included) and the Arguments is a proplist of the path and query string parameters. The key name for a path argument has the punctuation removed from the template and camel cases the second part. (example: :parent.id: -> parentId)

action(Data, Arguments) -> {ResposeCode, Response}.

For now, the primary implementation detail that leaks into the actions is the need to include a response code.

Defining Resource Metadata

Each resource should provide metadata as a seperate module. The following example demonstrates both the

-module(resource_type).
-export([metadata/0]).

metadata() ->
	[
		%% the inherit flag determines whether this resource's
		%% urls will be appended after a parent's url
		{inherit, false},

		%% define a root uri to prepend to all urls
		{root, "/api/parent"},

		%% the name of the callback module that will handle
		%% all actions for this resource
		{module, parent_server},

		{actions, [

			%% this action name will be the name of the link
			%% and the name of the function on the resource module
			{self, [

				%% controls which properties of the resource will
				%% be included in the response
				{properties, [id, title, description]},

				%% the url for this action.
				%% notice that path variables must be surrounded by ':'
				%% each variable should be two part, seperated by '.'
				%% the first part should be a resource and the second
				%% should be the property of the resource.
				{url, "/:parent.id:"},

				%% the method for this action
				{method, get},

				%% which resource properties should be included as
				%% embedded resources with their own actions
				{embed, [

					%% the property name of the resource
					{children, [

						%% the metadata module for the embedded resource
						{resource, child},

						%% the action to render for this resource
						{action, self},

						%% limits the number of embedded items to render
						{limit, 20},

						%% limits the number of actions to include (if any)
						{actions, [self]}
					]}
				]}
			]}
		]}
	].

To Do

  • Add support for template only hypermedia to generate slimmer responses
  • Fix defect in method filters on embedded resources
  • Add roles so that actions can be filtered based on caller role

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.