Skip to content

Commit

Permalink
Updated the Tutorial.
Browse files Browse the repository at this point in the history
  • Loading branch information
mtodd committed May 28, 2008
1 parent 1bb55b5 commit 22172e0
Showing 1 changed file with 98 additions and 58 deletions.
156 changes: 98 additions & 58 deletions content/docs/tutorial.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,71 +5,99 @@ filter:
- erb
- textile
---

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


h3. Installation

If you've not installed Halcyon yet, read the "Installation":/docs/installation.html guide.
If you've not installed Halcyon yet, read the
"Installation":/docs/installation.html guide.


h3. Starting a new application

If you're familiar with "Rails":http://rubyonrails.org/ or "Merb":http://merbivore.com/, 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.
If you're familiar with "Rails":http://rubyonrails.org/ or
"Merb":http://merbivore.com/, 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):
Run the following in your command line (make sure you're in a directory you're
OK having your project created in):

<pre><code>$ halcyon init app_name</code></pre>

This will generate output similar to the following:

<pre><code>
create
create runner.ru
create README
create config
create config/initialize.rb
create config/config.yml
create app
create app/application.rb
create Rakefile
create lib
create lib/client.rb
create log
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
</pre></code>

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

Now, change into the @app_name@ directory:

<pre><code>$ cd app_name</code></pre>

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.
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 <code>halcyon init -g</code>, the new application directory will
be initialized as a new Git repository. <code>-G</code> will go ahead and
commit the initial files.


h3. Running Halcyon Apps

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

<pre><code>halcyon start -p 4647</code></pre>

This tells Halcyon to start up the Halcyon application using either Rack's @rackup@ utility or Thin's @thin start@ utility (if "Thin":http://code.macournoyer.com/thin/ is installed) along with the port to run the server on.
This tells Halcyon to start up the Halcyon application using either Rack's
@rackup@ utility or Thin's @thin start@ utility (if
"Thin":http://code.macournoyer.com/thin/ is installed) along with the port to
run the server on.

You will see the following output:

<pre><code>
(Starting in /path/to/app_name)
DEBUG [2008-04-04 04:20:19] (11421) AppName :: Init: Initialize
DEBUG [2008-04-04 04:20:19] (11421) AppName :: Load: Application Controller
INFO [2008-04-04 04:20:19] (11421) AppName :: Starting up...
INFO [2008-04-04 04:20:19] (11421) AppName :: Initialize application resources and define routes in config/initialize.rb
DEBUG [2008-04-04 04:20:19] (11421) AppName :: Starting GC.
INFO [2008-04-04 04:20:19] (11421) AppName :: Started. PID is 11421
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
</code></pre>

This reveals a bit about its booting process and lets you know when it's ready to begin accepting connections.
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:

Expand All @@ -78,75 +106,79 @@ $ irb -r rubygems -r halcyon
>> client = Halcyon::Client.new('http://localhost:4647/')
=> #<Halcyon::Client ...>
>> client.get('/time')
=> {"status"=>200, "body"=>"Fri Apr 04 04:24:15 -0400 2008"}
=> {"status"=>200, "body"=>"Tue May 27 19:53:15 -0500 2008"}
>> exit
<% end -%>

What this does is, after requiring the Halcyon library, we create an instance of @Halcyon::Client@, telling it where to connect to.
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@.
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.
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.


h3. Modifying Your App


h4. 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.
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:

<% coderay(:lang => "ruby", :line_numbers => "inline", :tab_width => 2) do -%>
class Messages < Application
def new
# respond with fields acceptable
ok [:body, :title, :tags]
ok Model.columns
end
def create
case method
when :post
DB[:messages] << params.merge(:tags => params[:tags].join)
ok
when :get
# the params required for new messages
ok [:message, :tags]
else
raise NotImplemented
end
msg = Message.create(params.merge(:tags => params[:tags].join))
msg.save
ok msg.id
end
def read
ok DB[:messages][params[:id]]
ok Message[params[:id]]
end
def update
case method
when :post
DB[:messages].filter(:id => params[:id]).update(params)
ok
else
raise NotImplemented
end
Message.filter(:id => params[:id]).update(params)
ok
end
def delete
DB[:messages].filter(:id => params[:id]).delete
Message.filter(:id => params[:id]).delete
ok
end
end
<% end -%>

@DB@ refers to a "Sequel":http://code.google.com/p/ruby-sequel/ connection, which lets us talk to the @messages@ table. This could just as easily be a Sequel model, ActiveRecord model, or DataMapper model.
@Message@ refers to a "Sequel":http://code.google.com/p/ruby-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":/docs/controllers.html


h4. Routes

Part of developing a Halcyon app is writing the controllers, but requests need to be routed to the appropriate actions.
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:
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:

<% coderay(:lang => "ruby", :line_numbers => "inline", :tab_width => 2) do -%>
## /path/to/app_name/config/init/routes.rb
Halcyon::Application.route do |r|
r.match('/api/:version/:controller/:action(/:id)?').to()
r.default_routes
Expand All @@ -158,7 +190,10 @@ Read more about "Defining Routes":/docs/routes.html.

h4. 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:
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:

<% coderay(:lang => "ruby", :line_numbers => "inline", :tab_width => 2) do -%>
>> class MessageClient < Halcyon::Client
Expand All @@ -181,6 +216,11 @@ Read more about "Customizing Clients":/docs/clients.html

h2. 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":/docs/routes.html, "Writing Controllers":/docs/controllers.html, and "Customizing Clients":/docs/clients.html.
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":/docs/routes.html,
"Writing Controllers":/docs/controllers.html, and
"Customizing Clients":/docs/clients.html.

Still confused? Read a more thorough "Introduction to Halcyon":/docs/introduction.html.
Still confused? Read a more thorough
"Introduction to Halcyon":/docs/introduction.html.

0 comments on commit 22172e0

Please sign in to comment.