This page provides a technical overview of the Crest HTTP client library for Crystal, including its architecture, core components, and capabilities.
Crest is an HTTP and REST client library for Crystal that wraps the standard library's HTTP::Client to provide higher-level abstractions for common HTTP operations. The library is inspired by Ruby's RestClient gem.
The main module is defined in src/crest.cr1-72 and distributed as the crest shard. The current version is 1.6.2 as specified in shard.yml2 and CHANGELOG.md5
Primary capabilities:
Sources: src/crest.cr1-72 shard.yml1-29 README.md17-31 CHANGELOG.md5
Crest uses a three-tier architecture where multiple public APIs funnel through a common execution layer that delegates to Crystal's standard library HTTP::Client.
Component Architecture with Code Entities
This diagram maps the public API classes (Crest module in src/crest.cr Crest::Request in src/crest/request.cr Crest::Resource in src/crest/resource.cr) to the execution layer method Crest::Request#execute, which coordinates parameter encoding via Crest::ParamsEncoder#encode, form generation via Crest::DataForm and Crest::UrlencodedForm, and HTTP execution via HTTP::Client#exec from Crystal's standard library.
Sources: src/crest.cr36-69 Diagram 1 from architectural context
| Component | File Location | Primary Responsibility | Key Methods/Classes |
|---|---|---|---|
Crest module | src/crest.cr36-69 | Static convenience methods generated via metaprogramming for HTTP verbs | Crest.get, Crest.post, Crest.put, Crest.delete, Crest.patch, Crest.options, Crest.head (defined in src/crest.cr44-68) |
Crest::Request | src/crest/request.cr | Request builder and executor with full configuration options | Request.new(:method, url, form, **options), Request#execute, Request.get/post/put/delete/patch/options/head |
Crest::Resource | src/crest/resource.cr | RESTful resource abstraction maintaining base URL and default configuration | Resource.new(url, **defaults), Resource#[], Resource#get/post/put/delete/patch/options/head |
Crest::Response | src/crest/response.cr | Wrapper around HTTP::Client::Response with convenience accessors | Response#body, Response#body_io, Response#status, Response#status_code, Response#headers, Response#cookies, Response#history |
Crest::Redirector | src/crest/redirector.cr | Handles automatic redirect following with history tracking | Redirector.new(request, response), Redirector#follow |
Crest::ParamsEncoder | src/crest/params_encoder.cr | Abstract base class for parameter encoding strategies | ParamsEncoder#encode, FlatParamsEncoder, NestedParamsEncoder, EnumeratedFlatParamsEncoder, ZeroEnumeratedFlatParamsEncoder |
Crest::DataForm | src/crest/forms/data_form.cr | Handles multipart/form-data encoding for file uploads | DataForm#generate_body_string |
Crest::UrlencodedForm | src/crest/forms/urlencoded_form.cr | Handles application/x-www-form-urlencoded encoding | UrlencodedForm#generate |
Crest::Logger | src/crest/logger.cr | Abstract logging interface with regex-based filtering | Logger#request, Logger#response, Logger#filter, CommonLogger |
Crest::Curlify | src/crest/curlify.cr | Converts Crest::Request to equivalent cURL commands | Curlify.new(request), Curlify#to_curl |
Crest::ParamsDecoder | src/crest/params_decoder.cr | Decodes URL query strings into parameter hashes | ParamsDecoder.decode(query_string) |
Sources: src/crest.cr36-69 README.md44-77 Diagrams 1 and 4 from architectural context
Requests flow through a multi-stage pipeline: parameter encoding, form preparation, authentication setup, HTTP execution, response wrapping, redirect handling, and error processing.
Request Execution Sequence with Method Calls
This diagram shows the method call chain from Crest.get through Request.new, Request#execute, ParamsEncoder#encode, HTTP::Client#exec, Response.new, and Redirector#follow, illustrating how parameters, authentication, logging, and redirect handling integrate into the execution flow.
Sources: Diagram 2 from architectural context, src/crest.cr44-68
The execution pipeline consists of the following stages:
Request.new(:method, url, form, **options) validates parameters and stores configurationParamsEncoder#encode (default: FlatParamsEncoder)DataForm#generate_body_string (multipart) or UrlencodedForm#generate (urlencoded)Authorization header is set for HTTP Basic or Digest authenticationHTTP::Proxy from the http_proxy shard configures proxy settings if specifiedOpenSSL::SSL::Context::Client is applied for HTTPS requestsHTTP::Client#exec performs the actual network requestResponse.new(http_client_response, request) wraps the stdlib responseRedirector#follow recursively calls Request#execute for 3xx status codeshandle_errors: true, non-success status codes raise exceptions from the Crest::RequestFailed hierarchySources: Diagram 2 from architectural context, README.md81-111
Configuration Loading: The request gathers parameters including URL, method, headers, authentication credentials, proxy settings, and timeouts.
Parameter Encoding: Query parameters are encoded using a ParamsEncoder strategy. The default is Crest::FlatParamsEncoder which produces key[] notation for arrays.
Authentication: If credentials are provided via :user and :password parameters, the library applies HTTP Basic or Digest authentication by setting appropriate headers.
HTTP Execution: The request is delegated to Crystal's HTTP::Client from the standard library, which handles the actual network communication.
Response Wrapping: The raw HTTP::Client::Response is wrapped in a Crest::Response object that provides convenience methods.
Redirect Following: If the status code indicates a redirect (301-308) and :max_redirects is not zero, the Redirector component automatically follows the redirect chain.
Error Handling: If :handle_errors is true (default) and the response has an error status code, an exception is raised from the Crest::RequestFailed hierarchy.
Sources: Diagram 2 from context, README.md81-111
Crest provides three entry points that all converge on Crest::Request#execute:
The Crest module in src/crest.cr36-69 defines seven HTTP verb methods generated via metaprogramming in src/crest.cr44-68:
Each method instantiates Crest::Request and calls request.execute. Block variants yield Crest::Response for streaming.
Supported keyword arguments (partial list from README.md88-111):
:headers - Hash containing request headers:cookies - Hash containing request cookies:params - Hash or String for query parameters:params_encoder - Parameter encoder class (default: Crest::FlatParamsEncoder):auth - Authentication method (:basic or :digest):user and :password - Authentication credentials:json - Boolean to send JSON payload with appropriate headers:max_redirects - Maximum redirect count (default: 10):logging - Enable logging (default: false):handle_errors - Raise exceptions for error status codes (default: true)Sources: src/crest.cr36-69 README.md44-77 README.md81-111
The Crest::Request class in src/crest/request.cr provides both class methods and instance methods:
Class methods (static constructors):
Request.get(url, form, **args)Request.post(url, form, **args)Request.put(url, form, **args) (etc. for all HTTP verbs)Request.execute(:method, url, form, **args)Instance methods:
Request.new(:method, url, form, **args) - Constructorrequest.execute - Execute the request and return Crest::Responserequest.to_curl - Generate equivalent cURL commandrequest.close - Close the underlying HTTP connectionrequest.closed? - Check if connection is closedThe class also accepts a block during initialization to modify the request before execution.
Sources: README.md79-161 README.md114-122
The Crest::Resource class in src/crest/resource.cr maintains default configuration that applies to all requests:
Constructor:
Subresource allocation:
resource["/subpath"] - Returns new Resource with concatenated URL and inherited defaultsHTTP verb methods:
resource.get(suburl, form, **args)resource.post(suburl, form, **args) (etc.)Final parameters for each request are merged from: (1) defaults from Resource.new, (2) per-request arguments.
Sources: README.md163-248 README.md179-228
Authentication Methods:
| Method | Configuration | Implementation |
|---|---|---|
| HTTP Basic | user: "username", password: "secret" | Base64-encoded Authorization: Basic header set by Crest::Request |
| HTTP Digest | auth: "digest", user: "username", password: "secret" | HTTP::Client::DigestAuth from http-client-digest_auth shard (version >= 0.6.0 per shard.yml13-15) |
TLS/SSL Support:
tls: OpenSSL::SSL::Context::Client parameterCrest.get("https://expired.badssl.com", tls: OpenSSL::SSL::Context::Client.insecure)Sources: README.md478-511 shard.yml13-15 CHANGELOG.md99
Parameter encoding uses a strategy pattern with the abstract Crest::ParamsEncoder class in src/crest/params_encoder.cr Four concrete encoders are provided:
| Encoder Class | Array Encoding | Example Output | Added |
|---|---|---|---|
FlatParamsEncoder (default) | key[] notation | tags[]=ruby&tags[]=crystal | Initial release |
NestedParamsEncoder | Repeated keys | tags=ruby&tags=crystal | v1.1.0 (CHANGELOG.md133) |
EnumeratedFlatParamsEncoder | 1-based indexing | tags[1]=ruby&tags[2]=crystal | v1.2.0 (CHANGELOG.md112) |
ZeroEnumeratedFlatParamsEncoder | 0-based indexing | tags[0]=ruby&tags[1]=crystal | v1.2.0 (CHANGELOG.md112) |
Usage:
Encoder Methods:
ParamsEncoder#encode(params : Hash) : String - Converts hash to query stringParamsEncoder.flatten_params(object, parent_key) - Recursively flattens nested structuresSources: README.md319-376 CHANGELOG.md112-152 Diagram 4 from architectural context
Form encoding is automatically selected based on content type:
| Encoding | Content-Type Header | Trigger Condition | Handler Class |
|---|---|---|---|
| JSON | application/json | json: true option | Serialized via to_json |
| Multipart | multipart/form-data | Form includes File, IO, or Bytes | Crest::DataForm in src/crest/forms/data_form.cr |
| URL-encoded | application/x-www-form-urlencoded | Default for hash/string form data | Crest::UrlencodedForm in src/crest/forms/urlencoded_form.cr |
Multipart Features:
File.open, IO::Memory, and Bytes objectsapplication/octet-stream (added in v1.3.0 per CHANGELOG.md87)form: File.open("file.png") (added in v1.3.0 per CHANGELOG.md88-93)JSON Payload:
json: true to serialize form data to JSONContent-Type: application/json headerCrest.post(url, {"key" => "value"}, json: true)Sources: README.md405-441 CHANGELOG.md87-93 Diagram 2 from architectural context
The Crest::Redirector class in src/crest/redirector.cr automatically follows redirects:
Redirect Behavior:
max_redirects option)max_redirects: 0 to disable redirect followingResponse Properties:
Response#history : Array(Response) - Array of intermediate responsesResponse#requestExample:
Sources: README.md577-586 CHANGELOG.md333 Diagram 6 from architectural context
Block syntax enables streaming for large responses without loading entire body into memory:
Streaming API:
Key Methods:
Response#body_io : IO - IO handle for streaming response bodyResponse#filename : String? - Extract filename from Content-Disposition headerResponse#content_length : Int64 - Response size from Content-Length headerImplementation:
Crest.get, Request.get, Resource.get) support block syntaxCrest::Response with body_io available for streamingSources: README.md378-398 CHANGELOG.md329-333
Logging System:
The Crest::Logger abstract class in src/crest/logger.cr provides logging with two required methods:
Logger#request(request : Crest::Request) - Log outgoing requestLogger#response(response : Crest::Response) - Log incoming responseDefault Logger:
Crest::CommonLogger - Colorized console output with timestamp, method, and URLcrest | 2018-07-04 14:49:49 | GET | http://httpbin.org/getSensitive Data Filtering:
Custom Loggers:
Extend Crest::Logger and override request and response methods, then pass via logger: parameter.
cURL Command Generation:
The Crest::Curlify class in src/crest/curlify.cr converts requests to cURL commands:
Available via:
Request#to_curl instance methodResponse#to_curl delegated methodCrest::Curlify.new(request).to_curl direct usageSources: README.md537-575 README.md620-651 CHANGELOG.md359
HTTP/HTTPS proxy support via the http_proxy shard (version >= 0.14.0 per shard.yml16-18):
Proxy Parameters:
p_addr : String - Proxy hostname or IP addressp_port : Int32 - Proxy port numberp_user : String? - Proxy authentication username (optional)p_pass : String? - Proxy authentication password (optional)Example:
Behavior:
Sources: README.md513-535 shard.yml16-18 CHANGELOG.md417
Crest defines status-code-specific exceptions in src/crest/exceptions.cr All inherit from Crest::RequestFailed.
| Exception Class | HTTP Status Codes | Base Class |
|---|---|---|
Crest::RequestFailed | All non-success codes | Base exception |
Crest::BadRequest | 400 | RequestFailed |
Crest::Unauthorized | 401 | RequestFailed |
Crest::Forbidden | 403 | RequestFailed |
Crest::NotFound | 404 | RequestFailed |
Crest::MethodNotAllowed | 405 | RequestFailed |
Crest::RequestTimeout | 408 | RequestFailed |
Crest::Conflict | 409 | RequestFailed |
Crest::Gone | 410 | RequestFailed |
Crest::UnprocessableEntity | 422 | RequestFailed |
Crest::InternalServerError | 500 | RequestFailed |
Crest::NotImplemented | 501 | RequestFailed |
Crest::BadGateway | 502 | RequestFailed |
Crest::ServiceUnavailable | 503 | RequestFailed |
Crest::Found | 302 | RequestFailed |
Crest::MovedPermanently | 301 | RequestFailed |
Crest::RedirectLimitReached | - | RequestFailed |
Default Behavior (handle_errors: true):
Crest::Responsemax_redirects > 0)Access Response from Exception:
Disable Exception Raising (handle_errors: false):
When Added: Exception hierarchy introduced in v0.9.10 (CHANGELOG.md395-396)
Sources: README.md266-317 CHANGELOG.md395-396
Crest integrates with several external libraries and Crystal standard library components:
From shard.yml12-18:
The library builds on Crystal's standard library:
HTTP::Client: Core HTTP protocol implementationHTTP::Cookie: Cookie handlingOpenSSL::SSL::Context::Client: TLS/SSL supportURI::Punycode: International Domain Name support (mentioned in CHANGELOG.md240)MIME: MIME type detection for file uploadsSources: shard.yml12-18 src/crest.cr1-8 CHANGELOG.md240
Current version: 1.6.1 (released 2026-02-05) as documented in CHANGELOG.md5 and shard.yml2
Crystal compatibility: Requires Crystal >= 1.0.0 as specified in shard.yml10
The library maintains a detailed changelog at CHANGELOG.md1-507 documenting breaking changes, new features, and bug fixes across 40+ releases since the initial 0.9.2 release in November 2017.
Sources: CHANGELOG.md1-507 shard.yml2-10
Refresh this wiki
This wiki was recently refreshed. Please wait 7 days to refresh again.