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
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
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}}
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.