onyx-http-deprecated v0.1.1
Onyx::HTTP
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::Handler
s 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
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
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
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
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
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!
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:
- Onyx::HTTP Gitter chat
- Onyx Framework Gitter community
- Vlad Faust Gitter community
- Onyx Framework Twitter
- Onyx Framework Telegram channel
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
- Fork it ( https://github.com/onyxframework/http/fork )
- Create your feature branch (git checkout -b my-new-feature)
- Commit your changes (git commit -am 'feat: some feature') using Angular style commits
- Push to the branch (git push origin my-new-feature)
- Create a new Pull Request
Contributors
- Vlad Faust - creator and maintainer
Licensing
This software is licensed under MIT License.
onyx-http-deprecated
- 6
- 0
- 0
- 0
- 2
- over 5 years ago
- January 31, 2019
MIT License
Wed, 06 Nov 2024 15:34:53 GMT