crest
Simple HTTP and REST client for Crystal, inspired by the Ruby's RestClient gem.
Installation
Add this to your application's shard.yml
:
dependencies:
crest:
github: mamantoha/crest
Usage
require "crest"
Basic usage:
Crest.get("http://example.com/resource", params: {:lang => "ua"})
Crest.post("http://example.com/resource", payload: {:params1 => "one", :nested => {:params2 => "two"}})
Passing advanced options
Crest::Request
accept next parameters:
Mandatory parameters:
:method
- HTTP method (:get
.:post
,:put
,:patch
,:delete
):url
- URL (e.g.: "http://httpbin.org/ip")
Optional parameters:
:payload
- a hash containing query params:headers
- a hash containing the request headers:cookies
- a hash containing the request cookies:params
- a hash that represent query-string separated from the preceding part by a question mark (?
) a sequence of attribute–value pairs separated by a delimiter (&
):user
and:password
- for Basic Authentication:p_addr
,:p_port
,:p_user
, and:p_pass
- specify a per-request proxy by passing these parameters:max_redirects
- maximum number of redirections (default to 10):logging
- enable logging (default tofalse
):logger
- set logger (default toCrest::CommonLogger
)
More detailed examples:
Crest::Request.new(:get, "http://example.com/resource", headers: {"Content-Type" => "application/json"})
Crest::Request.new(:delete, "http://example.com/resource/1", params: {:lang => "ua"})
Crest::Request.new(:post, "http://example.com/resource", headers: {"Content-Type" => "application/json"}, payload: {:foo => "bar"})
Crest::Request.new(:patch, "http://example.com/resource/1", headers: {"Content-Type" => "application/json"}, payload: {:foo => "bar"})
Crest::Request.new(:get, "http://example.com/resource", user: "admin", password: "1234")
Multipart
Yeah, that's right! This does multipart sends for you!
file = File.open("#{__DIR__}/example.png")
Crest.post("http://example.com/upload", payload: {:image => file})
JSON payload
crest
does not speak JSON natively, so serialize your payload to a string before passing it to crest
.
Crest.post("http://example.com/", headers: {"Content-Type" => "application/json"}, payload: {:foo => "bar"}.to_json)
Headers
Request headers can be set by passing a hash containing keys and values representing header names and values:
response = Crest.get("http://httpbin.org/headers", headers: {"Authorization" => "Bearer cT0febFoD5lxAlNAXHo6g"})
response.headers
# => {"Authorization" => ["Bearer cT0febFoD5lxAlNAXHo6g"]}
Cookies
Request
and Response
objects know about HTTP cookies, and will automatically extract and set headers for them as needed:
response = Crest.get("http://httpbin.org/cookies/set", params: {"k1" => "v1", "k2" => "v2"})
response.cookies
# => {"k1" => "v1", "k2" => "v2"}
response = Crest.get("http://httpbin.org/cookies", cookies: {"k1" => "v1"})
response.cookies
# => {"k1" => "v1"}
Basic authentication
For basic access authentication for an HTTP user agent you should to provide a user name and password when making a request.
Crest.get("http://httpbin.org/basic-auth/user/passwd", user: "user", password: "passwd")
Proxy
If you need to use a proxy, you can configure individual requests with the proxy host and port arguments to any request method:
Crest.get("http://httpbin.org/ip", p_addr: "localhost", p_port: 3128)
To use HTTP Basic Auth with your proxy, use next syntax:
Crest.get("http://httpbin.org/ip", p_addr: "localhost", p_port: 3128, p_user: "user", p_pass: "qwerty")
Logging
By default, the Crest
does not enable logging. You can enable it per request by setting logging: true
:
Crest.get("http://example.com/resource", logging: true)
You can create the custom logger by integration Crest::Logger
abstract class.
Here has two methods must be implement: Crest::Logger.request
and Crest::Logger.response
.
class MyLogger < Crest::Logger
def request(request)
@logger.info ">> | %s | %s" % [request.method, request.url]
end
def response(response)
@logger.info "<< | %s | %s" % [response.status_code, response.url]
end
end
Crest.get("http://example.com/resource", logging: true, logger: MyLogger.new)
Resource
resource = Crest::Resource.new("http://localhost", headers: {"Content-Type" => "application/json"})
resource.get({"X-Something" => "1"})
Resource Nesting
site = Crest::Resource.new('http://example.com')
response = site["/api/article"].post({:title => "Hello world", :body => "Crystal is awesome!"})
Exceptions
- for result codes between
200
and207
, aCrest::Response
will be returned - for result codes
301
,302
,303
or307
, the redirection will be followed and the request transformed into aGET
- for other cases, a
Crest::RequestFailed
holding the Response will be raised - call
.response
on the exception to get the server's response
Redirection
By default, crest
will follow HTTP 30x redirection requests.
To disable automatic redirection, set :max_redirects => 0
.
Crest::Request.execute(method: :get, url: "http://httpbin.org/redirect/1", max_redirects: 0)
# Crest::RequestFailed: 302 Found
Result handling
The result of a Crest::Request
is a Crest::Response
object.
Response objects have several useful methods.
Response#body
: The response body as a stringResponse#status_code
: The HTTP response codeResponse#headers
: A hash of HTTP response headersResponse#cookies
: A hash of HTTP cookies set by the serverResponse#request
: TheCrest::Request
object used to make the requestResponse#http_client_res
: TheHTTP::Client::Response
objectResponse#history
: A list of each response received in a redirection chain
Development
Install dependencies:
shards
To run test:
make test
Contributing
- Fork it ( https://github.com/mamantoha/crest/fork )
- Create your feature branch (git checkout -b my-new-feature)
- Commit your changes (git commit -am 'Add some feature')
- Push to the branch (git push origin my-new-feature)
- Create a new Pull Request
Contributors
- mamantoha Anton Maminov - creator, maintainer
License
Copyright: 2017 Anton Maminov (anton.maminov@gmail.com)
This library is distributed under the MIT license. Please see the LICENSE file.