Halcyon Atl RUG Presentation

Preview:

DESCRIPTION

My presentation on Halcyon, the JSON web app framework.

Citation preview

Halcyon

I WORK

occasionally

HALCYON

web app framework

HALCYON

JSON

HTTP

Rack

Merb

light weight data transport layer

cross-platform communications layer

app/server abstraction layer

core extensions & router

JSON

similar to XML

easy to read & write (unlike XML)

serializable

cross platform

HTTP

cross platform

request/response model

REST

uniform resource identifiers

Rack

small core

simple rules

powerful abstractions

Jim Weirich

Merb

modular

active community, ever increasing code quality

well documented

easy

GETTING STARTED

installation, initialization,running, and customization

Installation

$ sudo gem install --source=http://halcyon.rubyforge.org/latest/

or

$ git clone git://github.com/mtodd/halcyon.git$ cd halcyon; rake install

$ sudo gem install json

Initialization

$ cd ~/Projects/$ halcyon init app_name

Running

$ cd ~/Projects/app_name/$ halcyon run -p 4647

or

$ thin start -p 4647as of Thin 0.8.0

Customization

CONTROLLERS

ROUTES

CLIENTS

found in app/inherits from Application

found in config/initializer.rbwill be config/initializers/routes.rb

found in lib/client.rbsimplifies calling actions' URLs

Controllers

class Foo < Application def random ok rand(10) end def greet ok "Hello #{params[:name]}!" end end

app/foo.rb

Routes

class Halcyon::Application route do |r| r.match('/hello/:name').to(:controller => 'foo') r.match('/rand').to(:controller => 'foo', :action => 'random') # defines /:controller/:action/:id and family # r.default_routes end end

config/initialize.rb

Clients

class AppAgent < Halcyon::Client def greet(name) get("/hello/#{name}")[:body] end def random get('/rand')[:body] end end

lib/client.rb

Run & Test

RUN

TEST

$ halcyon start -p 4647

$ irb -rubygems -r lib/client>> client = AppAgent.new( "http://localhost:4647/")=> #<AppAgent>>> client.rand=> 4>> client.greet("Matt")=> "Hello Matt!">> client.get("/foo")=> {:status=>404,:body=>"Not Found"}

Run & Test Interactively

OR $ halcyon irb>> get "/rand"=> {:status=>200,:body=>7}>> get "/hello/Matt"=> {:status=>200,:body=>"Hello Matt!"}>> client.get("/foo")=> {:status=>404,:body=>"Not Found"}

ADVANCED TOPICS

databases, Rack magic

DATABASES – ORM agnostic

ActiveRecord

DataMapper

Sequel

ET AL

in config/initialize.rbclass Halcyon::Application startup do |config| # connect to DB of your choice here. # define in $global_variable (bleh) # or Constant. end end

RACK MAGIC

API Handler

Cascade

Content-Type

Reloader

Referrer

routes matching pattern deferred

finds the first app that can handle request

change the content type for all responses

reload classes when modified

track referrers

class ApiHandler def initialize(app, api); @app, @api = app, api; end def call(env) req = Merb::Request.new(env) if request.path =~ %r{^/api/(.*)} @api.call(env) else @app.call(env) end endenduse ApiHandler, Halcyon::Runner.newrun Merb::Rack::Application.new

RACK MAGIC – API Handler

Similar to previous example, only using Rack::Cascade.

run Rack::Cascade, [ Halcyon::Runner.new, Merb::Rack::Application.new]

Just define routes so that the Halcyon app won't preventthe Merb app from ever running.(Require /api/ in front of all routes for Halcyon, forinstance.)

RACK MAGIC – Cascade

# http://hokstad.com/rewriting-content-types-with-rack.html

class RewriteContentType def initialize(app, map); @app, @map = app, map; end def call(env) res = @app.call(env) type = res[1]["Content-Type"] res[1]["Content-Type"] = @map[type] if @map.has_key?(type) res endend

use RewriteContentType, {'application/json'=>'text/plain'}run Halcyon::Runner.new

RACK MAGIC – Content Type

Automatically reload modified requirements.

# uncomment for pretty web exception rendering# use Rack::ShowExceptionsuse Rack::Reloaderrun Halcyon::Runner.new

Simple as that.

RACK MAGIC – Reloader

Keep a log of referring links (if even set), or any other recordable data.

http://hokstad.com/latest-referrers-using-rack-and-ruby.html

Why reinvent the wheel?

RACK MAGIC – Referrer

DEMO

QUESTIONS?

RESOURCES

HOMEPAGE

GIT REPO

DOCS

IRC

Jan Lenhardt's MountainWest CouchDB Talk

http://halcyon.rubyforge.org/

http://github.com/mtodd/halcyon

http://halcyon.rubyforge.org/docs/

freenode.net #halcyon

http://mtnwestrubyconf2008.confreaks.com/10lehnardt.html

FIN

SEE ALSO

CouchDB

Jan Lenhardt's MountainWest CouchDB Talk

http://couchdb.com/

http://mtnwestrubyconf2008.confreaks.com/10lehnardt.html