01 Hello - kjellhex/diode GitHub Wiki

Code

Let's build a simple Hello World server. Put the following into a file named hello-server.rb:

class Hello
  def serve(request)
    body = JSON.dump({ "message": "Hello World!" })
    Diode::Response.new(200, body)
  end
end

require 'diode/server'
routing = [
  [%r{^/}, "Hello"]
]
server = Diode::Server.new(3999, routing)
server.start()

Run the server:

$ ruby hello-server.rb

and visit the page at http://localhost:3999/ to see the JSON message. Note that it has Content-Type: application/json by default.

How does it work?

Service

The Hello class is the service. It can do anything you like, but to function as a Diode service, it needs to respond to the method #serve. The serve method is given a Diode::Request as its argument. The request has lots of features, but while we ignore them all here for simplicity. No matter what the request, the service simply returns a welcome message.

def serve(request)
  body = JSON.dump({ "message": "Hello World!" })
  Diode::Response.new(200, body)
end

Response

The method creates the response body as a JSON message, and then creates a Diode::Response to return to the server. The Diode::Response takes arguments of the HTTP status code (in this case 200 OK), and an optional response body. In this example, we omit the optional hash of HTTP Response headers for simplicity, but Diode is built in ruby-style for developer convenience, so the response will be given a few essential headers automatically:

  • Content-Type
  • Date
  • Cache-Control
  • Server
  • Connection
  • Content-Length

Server

Next we need to require diode/server to load the Diode::Server, Diode::Request, Diode::Response and Diode::Static.

When you have many services in an application, the routing specifies which services support each path pattern. In this case, since we have only one service, all requests with paths starting with "/" (which is all) are passed to the service named "Hello". The %r{} syntax is convenient because it means you do not have to escape slashes in your path patterns. So this first routing rule says "for any request matching this pattern, create an instance of Hello and call the serve() method, passing the request as the argument.

routing = [
  [%r{^/}, "Hello"]
]

After the pattern, the second item in the list is a String, the name of the class of the service. Since it is a string, the class of that name does not already need to be loaded into memory. But by the time you create the server and provide it with routing instructions, all service classes must have been defined and loaded becasue the server will validate that each service class exists.

Starting

server = Diode::Server.new(3999, routing).start()

The server starts, listens on port 3999, using the routing rules that have been set up, and will respond to all requests by invoking the Hello service.

Congatulations! You have built your first Diode-powered REST application server.

Although this is a very simple example, you can probably see how useful this could be when you need to quickly build a REST API to produce a certain response for testing.

Next

Ready for more? 02 Configuration shows how service configuration and application settings work.