This repository has been archived by the owner. It is now read-only.

onyx-http-deprecated v0.1.1

Deprecated Onyx module

Onyx::HTTP

Built with Crystal Travis CI build API docs Latest release

An HTTP framework for Crystal.

Supporters ❤️

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

Lauri Jutila, Alexander Maslov, Dainel Vera

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

About 👋

Onyx::HTTP is a collection of HTTP::Handler's to use in web Crystal applications. It also includes a convenient HTTP::Server wrapper. Onyx::HTTP shard serves as a foundation for higher-level Onyx components, such as Onyx::REST, but it can definetely be used as a stand-alone library.

Installation 📥

Add this to your application's shard.yml:

dependencies:
  onyx-http:
    github: onyxframework/http
    version: ~> 0.2.0

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 💻

Onyx::HTTP includes multiple useful HTTP::Handlers and an HTTP::Server wrapper. If you don't know anything about the Crystal HTTP server, then check out its official docs and API before continuing.

Simple server

Start with a simple Onyx::HTTP::Server example:

require "onyx-http"

server = Onyx::HTTP::Server.new do |env|
  env.response << "Hello Onyx"
end

server.bind_tcp(5000)
server.listen
> curl http://localhost:5000
Hello Onyx

Screenshot #1

Logging

We'd like to see the actual request in the STDOUT. Use Onyx::HTTP::Logger for that:

require "onyx-http"

logger = Onyx::HTTP::Logger.new

server = Onyx::HTTP::Server.new(logger) do |env|
  env.response << "Hello Onyx"
end

server.bind_tcp(5000)
server.listen
> curl http://localhost:5000
Hello Onyx

Screenshot #2

Request meta

It's a good idea to add an ID to the request and also a time elapsed to process it for further analysis. There are Onyx::HTTP::RequestID and Onyx::HTTP::ResponseTime handlers:

require "onyx-http"

logger = Onyx::HTTP::Logger.new
request_id = Onyx::HTTP::RequestID.new
response_time = Onyx::HTTP::ResponseTime.new

server = Onyx::HTTP::Server.new(response_time, request_id, logger) do |env|
  env.response << "Hello Onyx"
end

server.bind_tcp(5000)
server.listen
> curl http://localhost:5000 -v
* Rebuilt URL to: http://localhost:5000/
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 5000 (#0)
> GET / HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Connection: keep-alive
< X-Request-ID: 14c0259b-c020-4c85-931c-556e1ff266da
< X-Response-Time: 120
< Content-Length: 10
<
* Connection #0 to host localhost left intact
Hello Onyx

Screenshot #3

CORS

Modern APIs usually require proper CORS handling. It is achievable with Onyx::HTTP::CORS:

require "onyx-http"

logger = Onyx::HTTP::Logger.new
request_id = Onyx::HTTP::RequestID.new
response_time = Onyx::HTTP::ResponseTime.new
cors = Onyx::HTTP::CORS.new

server = Onyx::HTTP::Server.new(response_time, request_id, logger, cors) do |env|
  env.response << "Hello Onyx"
end

server.bind_tcp(5000)
server.listen

> curl http://localhost:5000 -v
* Rebuilt URL to: http://localhost:5000/
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 5000 (#0)
> GET / HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Connection: keep-alive
< X-Request-ID: af4ded9e-2f72-41aa-bac2-308b38198af6
< Access-Control-Allow-Origin: *
< X-Response-Time: 233
< Content-Length: 10
<
* Connection #0 to host localhost left intact
Hello Onyx

Routing

Almost every web application requires routing. It is quite simple with Onyx::HTTP::Router:

require "onyx-http"

logger = Onyx::HTTP::Logger.new
request_id = Onyx::HTTP::RequestID.new
response_time = Onyx::HTTP::ResponseTime.new

router = Onyx::HTTP::Router.new do
  get "/" do |env|
    env.response << "Hello Onyx"
  end

  post "/echo" do |env|
    env.response << env.request.body.try &.gets_to_end
  end
end

server = Onyx::HTTP::Server.new(response_time, request_id, logger, router)

server.bind_tcp(5000)
server.listen
> curl http://localhost:5000
Hello Onyx
> curl -X POST -d "Knock-knock" http://localhost:5000/echo
Knock-knock

Screenshot #4

Rescuing

By default, an unhandled exception would halt the request processing, put the error backtrace into STDERR and print 500 Internal Server Error into the response body. We can change this behaviour with Onyx::HTTP::Rescuer.

This shard comes with Onyx::HTTP::Rescuers::Standard, Onyx::HTTP::Rescuers::Silent and Onyx::HTTP::Rescuers::RouteNotFound:

require "onyx-http"

logger = Onyx::HTTP::Logger.new
request_id = Onyx::HTTP::RequestID.new
response_time = Onyx::HTTP::ResponseTime.new
rescuer = Onyx::HTTP::Rescuers::Standard(Exception).new
router_rescuer = Onyx::HTTP::Rescuers::RouteNotFound.new

router = Onyx::HTTP::Router.new do
  get "/" do |env|
    env.response << "Hello Onyx"
  end

  post "/echo" do |env|
    env.response << env.request.body.try &.gets_to_end
  end

  get "/error" do
    raise "Oops!"
  end
end

server = Onyx::HTTP::Server.new(response_time, request_id, logger, rescuer, router_rescuer, router)

server.bind_tcp(5000)
server.listen
> curl http://localhost:5000/error
500 Internal Server Error
> curl http://localhost:5000/unknown
404 Route Not Found: GET /unknown

Screenshot #5

Macros

Now that you know how Onyx::HTTP works on the low-level, you'd probably want to reduce the amount of boilerplate code in your applications. We've got you covered! @onyxframework/onyx shard contains many top-level macros just for your convenience:

require "onyx/env"
require "onyx/http"

Onyx.get "/" do |env|
  env.response << "Hello Onyx"
end

Onyx.listen

This example includes all the handlers listed above!

> curl http://localhost:5000 -v
* Rebuilt URL to: http://localhost:5000/
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 5000 (#0)
> GET / HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Connection: keep-alive
< X-Request-ID: 89bbea1c-26b8-4113-ab67-04279eb0fa13
< Access-Control-Allow-Origin: *
< X-Response-Time: 109
< Content-Length: 12
<
* Connection #0 to host localhost left intact
Hello, Onyx!

Screenshot #6

You can easily modify the server's middleware:

Onyx.listen do |handlers, server|
  # This code is going to be injected right before server.listen
  handlers.insert(1, MyCustomHandler.new)
end

Next steps

As said before in the about section, Onyx::HTTP is just a foundation for other Onyx components. You may now want to check Onyx::REST for a scalable REST API framework!

The decent Onyx::HTTP API documentation is always available at https://api.onyxframework.org/http.

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

Repository

onyx-http-deprecated

Owner
Statistic
  • 6
  • 0
  • 0
  • 0
  • 2
  • about 5 years ago
  • January 31, 2019
License

MIT License

Links
Synced at

Thu, 02 May 2024 11:34:09 GMT

Languages