responsible
Version, currently 1.2.36 versions
github.com/place-labs/responsible
HTTP response parser for crystal-lang
7 stars
1 dependent
License: MIT
Installation
# Add this to your shard.yml
dependencies:
responsible:
github: place-labs/responsible
version: ~> 1.2.3Then run:
shards installshard.yml
- Crystal
>= 0.34.0, < 2.0.0- License
- MIT
- Author
- Kim Burgess <kim@place.technology>
Dependencies
Development Dependencies
- webmock*github: manastech/webmock.cr, branch: masterdev
README
# Responsible
In the wise words of the modern poet Ice Cube:
> So come on and chickity check yo self before you wreck yo self
Responsible is a library that makes it simple, fast an easy to check HTTP responses in crystal-lang.
It provides a lightweight API for dealing with errors, logging and static, type-safe parsing.
It works directly with `HTTP::Client::Response` objects and can function in tandem with clients that build on top of these.
Third party libraries (like [halite](https://github.com/icyleaf/halitea), [crest](https://github.com/mamantoha/crest) and others) are [supported](#third-party-support) too.
## What this isn't
Responsible is not a HTTP client.
It *does not* handle request building, execution, retries, or authentication.
It deals purely with response objects once you already have them, regardless of their source.
## Installation
1. Add the dependency to your `shard.yml`:
```yaml
dependencies:
responsible:
github: place-labs/responsible
```
2. Run `shards install`
3. Load via:
```crystal
require "responsible"
```
## Usage
To become responsible, prefix any response or method that returns a response with `~`.
```crystal
response = ~HTTP::Client.get("https://www.example.com")
```
This allows a clear way to express what should happen when errors occur.
```crystal
response.on_server_error do
# oh noes
end
```
When working with JSON, it also lets you efficiently parse to type-safe objects.
```crystal
response = ~HTTP::Client.get("https://www.example.com") >> NamedTuple(message: String)
response[:message]
# => hello world
```
A small selection of macros are also provided to keep common tasks clean, clear and concise.
```crystal
def example_request_wrapper : { message: String }
Responsible.parse_to_return_type do
HTTP::Client.get("https://www.example.com")
end
end
```
---
Responsible Responses™ maintain all existing functionality of a vanilla response object.
```crystal
chuck_norris_response = ~HTTP::Client.get("https://api.chucknorris.io/jokes/random")
chuck_norris_response.body
# =>
{
"categories": [],
"created_at": "2020-01-05 13:42:19.897976",
"icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
"id": "h6EF5PXvQoK5cW60-lUeDg",
"updated_at": "2020-01-05 13:42:19.897976",
"url": "https://api.chucknorris.io/jokes/h6EF5PXvQoK5cW60-lUeDg",
"value": "Chuck Norris has a large, curved talon on each foot, much like the Velociraptor."
}
```
They also let you inject behaviour for dealing with different response scenarios.
```crystal
# Global handlers - this will apply to every reponse
Responsible.on_client_error do |response|
raise "I'm a teapot" if response.status_code == 418
end
# Local action - these apply to the target response
chuck_norris_response.on_redirect do |response|
my_request_method(response.headers["Location"])
end
```
To parse to a matching type use the `>>` operator.
```crystal
struct ChuckNorrisFact
include JSON::Serializable
getter created_at : Time
getter id : String
getter updated_at : Time
getter value : String
end
fact = chuck_norris_response >> ChuckNorrisFact
fact.value
# => Chuck Norris has a large, curved talon on each foot, much like the Velociraptor.
```
This also works inline for terse, type-safe, error checked responses.
```crystal
fact = ~HTTP::Client.get("https://api.chucknorris.io/jokes/random") >> NamedTuple(value: String)
fact[:value]
# => Chuck Norris can binary search unsorted data.
```
If the response format is incompatible with the specified type a `Responsible::Error` will raise.
This contains the parser exception via `error.cause`.
To return `nil` in place of a raising an error, use a nilable target type.
```crystal
chuck_norris_response >> Float64?
# => nil
```
## Again, but verbose-er-er
If the operator overloading is too terse, named methods are available.
To wrap a response object:
```crystal
response = HTTP::Client.get("www.example.com")
response = Responsible::Response.new(response)
```
This performs the same action as using the `~` operator.
To parse into a type:
```crystal
response.parse_to(MyType)
```
This is the same behaviour as `>>`.
An optional block argument supports defining custom parser error handling.
```crystal
response.parse_to(MyType) do |exception|
# Handle, raise or re-try as appropriate.
end
```
To return `nil` in case of a parser error, use:
```crystal
response.parse_to?(MaybeMyType)
```
## Third-party support
Responsible works around a [minimal response object interface](./src/responsible/response_interface.cr).
When you `require "responsible"`, support loads for `HTTP::Client::Response` objects by default.
To support third party response objects use the `Responsible.support` macro.
```crystal
require "Halite"
Responsible.support Halite::Response
response = ~Halite.get("https://www.example.com") >> NamedTuple(message: String)
response[:message]
```
## Contributors
- [Kim Burgess](https://github.com/KimBurgess) - creator and maintainer
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
1.2.3- Tagged
- Apr 19, 2021
- Commit
9b434ef62e43- Crystal
>= 0.34.0, < 2.0.0- Indexed
- yes
Dependents
Repository
github.com/place-labs/responsible
Metadata
- Created
- Aug 12, 2026
- Updated
- Aug 14, 2026
- Synced
- Aug 14, 2026
- Versions
- 6