onyx-http

REST API framework with type-safe params and separate business and rendering layers, based on onyx-http web framework router websockets modular http-handler onyxframework
0.6.1 released
onyxframework/http
141 11 7
Onyx Framework

Onyx::REST

Built with Crystal Travis CI build API docs Latest release

A REST API framework for Crystal.

Supporters ❤️

Thanks to all my patrons, I can continue working on beautiful Open Source Software! 🙏

Alexander Maslov, Lauri Jutila

You can become a patron too in exchange of prioritized support and other perks

About 👋

Onyx::REST is an opinionated REST API framework build on top of Onyx::HTTP. It provides modules to build scalabale applications, such as Action and View.

Installation 📥

Add this to your application's shard.yml:

dependencies:
  onyx-rest:
    github: onyxframework/rest
    version: ~> 0.6.1

This shard follows Semantic Versioning v2.0.0, so check releases and change the version accordingly. Please visit github.com/crystal-lang/shards to know more about Crystal shards.

Usage 💻

Note: you should make yourself familiar with Onyx::HTTP before using this shard.

Onyx::REST has two main concepts: actions and views. Action is where the business logic takes place, they are essentially REST endpoints. And views take care of rendering.

Actions

Action is a module and can be included into any object. Structs works nice, because actions do not need to reference each other, they are throw-away objects. There is no enforced one-to-one relation between actions and endpoints. Multiple endpoints can execute a single Action, and vice-versa. Let's define a simple action:

require "onyx-rest"

struct Hello
  include Onyx::REST::Action

  def call
    context.response << "Hello Onyx"
  end
end

router = Onyx::HTTP::Router.new do
  get "/", Hello
end

server = Onyx::HTTP::Server.new(router)
server.bind_tcp(5000)
server.listen
> curl http://localhost:5000
Hello Onyx

Actions have access to the current HTTP::Server::Context via #context getter. They also have have #status, #header and #redirect shortcuts.

Params

You can easily define strongly-typed parameters in Actions to enable it parsing incoming values from the HTTP request path, query and also form and JSON bodies. Nested and array params are supported as well.

require "onyx-rest"

struct Hello
  include Onyx::REST::Action

  params do
    query do
      type who : String
    end
  end

  def call
    context.response << "Hello #{params.query.who}"
  end
end

router = Onyx::HTTP::Router.new do
  get "/", Hello
end

server = Onyx::HTTP::Server.new(router)
server.bind_tcp(5000)
server.listen
> curl http://localhost:5000/?who=World
Hello World

This feature is proudly powered by HTTP::Params::Serializable shard. Read more about .params macro in API docs.

Errors

It's typical for web applications to have expected errors, e.g. "User is not found". Actions have syntax to define such errors (you'll need an Onyx::REST::Rescuer):

require "onyx-rest"

struct GetUser
  include Onyx::REST::Action

  params do
    path do
      type id : Int32
    end
  end

  errors do
    type UserNotFound(404)
  end

  def call
    if params.path.id == 42
      context.response << "Found user"
    else
      raise UserNotFound.new
    end
  end
end

rescuer = Onyx::REST::Rescuer.new

router = Onyx::HTTP::Router.new do
  get "/users/:id", GetUser
end

server = Onyx::HTTP::Server.new(rescuer, router)
server.bind_tcp(5000)
server.listen
> curl http://localhost:5000/users/42
Found user
> curl http://localhost:5000/users/43
404 User Not Found

Views

View is a module which responsibility is to render responses. A view should be handled by a renderer, which could either be Onyx::Renderers::Text or Onyx::Renderers::JSON:

require "onyx-rest"
require "onyx-rest/renderers/text"

struct UserView
  include Onyx::REST::View

  def initialize(@id : Int32, @name : String)
  end

  text("id: #{@id}, name: #{@name}")
end

router = Onyx::HTTP::Router.new do
  get "/" do |env|
    env.response.view = UserView.new(42, "John")
  end
end

renderer = Onyx::REST::Renderers::Text.new

server = Onyx::HTTP::Server.new(router, renderer)
server.bind_tcp(5000)
server.listen
> curl http://localhost:5000
id: 42, name: John

Actions + Views

Actions have two native integrations with views. The first one is #view method which sets the response view like this:

  def call
    view(UserView.new(42, "John"))
  end

And the second one is the fact that if an action returns a View, it is then treated as a response view (if not set eariler):

  def call
    return UserView.new(42, "John")
  end

or, for a prettier control flow:

  def call
    return UserView.new(42, "John") if something
    some_code
    return AnotherView.new
  end

Macros

You should use "onyx/rest" instead of "onyx/http" to enable Onyx::REST::Rescuer and an ability to enable a renderer in one line:

require "onyx/rest"

Onyx.render(:json)
Onyx.listen

Read more about Onyx::HTTP macros at @onyxframework/onyx#http or at @onyxframework/http#macros.

Community 🍪

There are multiple places to talk about this particular shard and about other ones as well:

Support ❤️

This shard is maintained by me, Vlad Faust, a passionate developer with years of programming and product experience. I love creating Open-Source and I want to be able to work full-time on Open-Source projects.

I will do my best to answer your questions in the free communication channels above, but if you want prioritized support, then please consider becoming my patron. Your issues will be labeled with your patronage status, and if you have a sponsor tier, then you and your team be able to communicate with me in private or semi-private channels such as e-mail and Twist. There are other perks to consider, so please, don't hesistate to check my Patreon page:

You could also help me a lot if you leave a star to this GitHub repository and spread the world about Crystal and Onyx! 📣

Contributing

  1. Fork it ( https://github.com/onyxframework/http/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'feat: some feature') using Angular style commits
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors

Licensing

This software is licensed under MIT License.

Open Source Initiative

onyx-http:
  github: onyxframework/http
  version: ~> 0.6.1
License MIT
Crystal 0.27.2

Authors

Dependencies 3

  • callbacks ~> 0.2.0
    {'github' => 'vladfaust/callbacks.cr', 'version' => '~> 0.2.0'}
  • http-params-serializable ~> 0.3.0
    {'github' => 'vladfaust/http-params-serializable', 'version' => '~> 0.3.0'}
  • onyx-http ~> 0.1.1
    {'github' => 'onyxframework/http', 'version' => '~> 0.1.1'}

Development Dependencies 0

Dependents 2

Last synced .
search fire star recently