Halcyon

Notice: The website is currently being udpated. Sorry for any inconvenience.

Tutorial

Coming to a new, unfamiliar framework can be daunting, especially with nobody
there to hold your hand through the scary bits. Hopefully this tutorial will
get you through those parts just fine and get you into developing cool
services.

Installation

If you’ve not installed Halcyon yet, read the
Installation guide.

Starting a new application

If you’re familiar with Rails or
Merb, you know that you can begin working on a new
application very easily by issuing a simple command, similar to
rails app_name. Halcyon provides a similar command to do the same.

Run the following in your command line (make sure you’re in a directory you’re
OK having your project created in):

$ halcyon init app_name

This will generate output similar to the following:


  create  
  create  app
  create  app/application.rb
  create  config
  create  config/config.yml
  create  config/init
  create  config/init/environment.rb
  create  config/init/hooks.rb
  create  config/init/requires.rb
  create  config/init/routes.rb
  create  lib
  create  lib/client.rb
  create  Rakefile
  create  README
  create  runner.ru
  create  log

This shows you what files were created, but more importantly, what files you’ll
be working with.

Now, change into the app_name directory:

$ cd app_name

You are now the proud owner of a brand new Halcyon application. Now would be a
good time to run git init to begin tracking your app under Git’s revision
control.

Note: With halcyon init -g, the new application directory will
be initialized as a new Git repository. -G will go ahead and
commit the initial files.

Running Halcyon Apps

So with our brand new application, let’s see what running our application looks
like:

halcyon start -p 4647

This tells Halcyon to start up the Halcyon application using either Rack’s
rackup utility or Thin’s thin start utility (if
Thin is installed) along with the port to
run the server on.

You will see the following output:


(Starting in /path/to/app_name)
DEBUG [2008-05-27 19:51:39] (9250) AppName :: Init: Requires
DEBUG [2008-05-27 19:51:39] (9250) AppName :: Init: Hooks
DEBUG [2008-05-27 19:51:39] (9250) AppName :: Init: Routes
DEBUG [2008-05-27 19:51:39] (9250) AppName :: Init: Environment
DEBUG [2008-05-27 19:51:39] (9250) AppName :: Load: Application Controller
 INFO [2008-05-27 19:51:39] (9250) AppName :: Starting up...
 INFO [2008-05-27 19:51:39] (9250) AppName :: Define startup tasks in config/init/hooks.rb
DEBUG [2008-05-27 19:51:39] (9250) AppName :: Starting GC.
 INFO [2008-05-27 19:51:39] (9250) AppName :: Started. PID is 9250

This reveals a bit about its booting process and lets you know when it’s ready
to begin accepting connections.

In another shell window, keeping your Halcyon app running, run the following:

1 $ irb -r rubygems -r halcyon
2 >> client = Halcyon::Client.new('http://localhost:4647/')
3 => #<Halcyon::Client ...>
4 >> client.get('/time')
5 => {"status"=>200, "body"=>"Tue May 27 19:53:15 -0500 2008"}
6 >> exit

What this does is, after requiring the Halcyon library, we create an instance
of Halcyon::Client, telling it where to connect to.

After the client is created, we can then perform requests using standard HTTP
request types, GET, POST, PUT, and DELETE. Here we simply call get('/time')
which gets routed to the time action inside of the Application controller
inside of app_name/app/application.rb.

Don’t worry, you’ll be able to wrap up get and post requests in your own
custom client methods and make corresponding actions in the actual Halcyon
application.

Modifying Your App

Controllers

Halcyon’s controllers all inherit from Halcyon::Controller which provides
several useful methods for responding in different situations, such as the
ok method to respond with the 200 OK standard HTTP success response, along
with any data you need to send back.

For example, a controller may look like this:

 1 class Messages < Application
 2   def new
 3     # respond with fields acceptable
 4     ok Model.columns
 5   end
 6   def create
 7     msg = Message.create(params.merge(:tags => params[:tags].join))
 8     msg.save
 9     ok msg.id
10   end
11   def read
12     ok Message[params[:id]]
13   end
14   def update
15     Message.filter(:id => params[:id]).update(params)
16     ok
17   end
18   def delete
19     Message.filter(:id => params[:id]).delete
20     ok
21   end
22 end

Message refers to a Sequel model,
which lets us talk to the messages table. This could just as easily be a
Sequel model, ActiveRecord model, or DataMapper model.

Read more about Writing Controllers

Routes

Part of developing a Halcyon app is writing the controllers, but requests need
to be routed to the appropriate actions.

There are, by default, no routes defined for an application, but there is a way
to quickly define routes as matching any variation of
/:controller/:action/:id, etc. Here is a sample, including a custom route as
well:

1 ## /path/to/app_name/config/init/routes.rb
2 Halcyon::Application.route do |r|
3   r.match('/api/:version/:controller/:action(/:id)?').to()
4   r.default_routes
5 end

Read more about Defining Routes.

Clients

The easiest way to communicate with your Halcyon application is with a Halcyon
client. By default, it creates a simple way to perform GET, POST, PUT, and
DELETE requests on application routes, but can be extended with methods that
easily corresponds with your routes. For example:

 1 >> class MessageClient < Halcyon::Client
 2 *>   def create(params)
 3 *>     post("/api/1.0/messages/create", params)
 4 *>   end
 5 *> end
 6 >> Message = MessageClient.new('http://localhost:4647/')
 7 => #<MessageClient>
 8 >> Message.create(:message => 'First test.', :tags => ['test', 'first'])
 9 => {'status' => 200, 'body' => {:id => 1}}
10 >> Message.post("/api/1.0/messages/create", :message => 'Second test.', :tags => [])
11 => {'status' => 200, 'body' => {:id => 2}}

You can also implement clients into your currently existing models.

Read more about Customizing Clients

What’s Next

Now that you know how to get things running, you’ll want to delve deeper into
learning just how to customize your application by reading
Defining Routes,
Writing Controllers, and
Customizing Clients.

Still confused? Read a more thorough
Introduction to Halcyon.