trapped / Moonshine

Web framework for Crystal language

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Moonshine Build Status

Moonshine is a minimal sinatra like web framework for the Crystal language. Code speaks louder than words, so here's an example.

require "moonshine"

include Moonshine
include Moonshine::Utils::Shortcuts
include Moonshine::Base

app = App.new

# respond to all HTTP verbs
app.route "/", do |request|
  ok("Hello Moonshine!")
end

# or particular HTTP verbs
app.get "/get", do |request|
  ok("This is a get response")
end

# you can set response headers
app.get "/api", do |request|
  res = ok("{\"name\": \"moonshine\"}")
  res.headers["Content-type"] = "text/json"
  res
end

app.run(8000)

Form Parameters

Moonshine automatically parses POST and GET parameters for you. The get and post properties are hashes of these params.

app.get "/putparams", do |request|
  ok("<h1>POST<h1><p>#{request.post}</p><h2>GET<h2><p>#{request.get}</p>")
end

Controllers

Controllers are objects which can respond to multiple routes. Set the @rotuer instance variable of a controller to specify routing within controller. Add the controller to the app using app.controller method. @router maps between a route and an action. Action can be any object with a call method (usually a Proc).

# subclass Moonshine::Base::Controller to define a controller
class HomeController < Moonshine::Base::Controller
  def initialize()
    @viewcount = 0
    @router = {
      "GET /" => ->get(Request),
    }
  end

  def get(req)
    @viewcount += 1
    ok("This page has been visited #{@viewcount} times.")
  end
end

# Bind controller to the app object
app.controller "/", HomeController.new

An action can also be a string containing the method name provided that the method is defined in the controller, and the controller name symbol has been passed to the actions macro in the controller definition.

class PostController < Moonshine::Base::Controller
  actions :get_all_posts, :get_post
  def initialize()
    @posts = [
          Post.new("Post1"),
          Post.new("Post2")
         ] of Post
    @router = {
      "GET /posts" =>"get_all_posts",
      "GET /posts/:id" => "get_post"
    }
  end

  def get_post(req)
    ...
  end

  def get_all_posts(req)
    ...
  end
end

app.controller(PostController.new)

String and proc actions can also be mixed in a single router.

Middleware

You can either create middleware classes or individual methods that process request or response

Middleware Classes

You can add middleware classes to your application by inheriting from Middleware::Base. Your class can override process_request and process_response methods to globally alter request and response objects.

class Hello < Moonshine::Middleware::Base
  def process_request(req)
    req.headers["User"] = "Annonymous"
  end

  def process_response(req, res)
    req.body += "\nFooter"
  end
end
app.middleware_object Hello.new

Request Middleware

# add request middleware
app.request_middleware do |req|
  unless req.get.has_key? "user"
    Moonshine::Http::Response.new(200, "Not allowed")
  else
    nil
  end
end

To add a request middleware, call app.request_middleware with a block that returns a response or nil. If the method returns nil, the response chain continues, otherwise, the response is sent back.

Response Middleware

# add response middleware
app.response_middleware do |req, res|
  res.body = "Modified"
  res
end

Response middleware methods take request and response arguments and return a response. This is used to globally alter the response of the application. Response middleware are processed in order.

About

Web framework for Crystal language

License:MIT License


Languages

Language:Crystal 100.0%