• Stars
    star
    769
  • Rank 56,630 (Top 2 %)
  • Language
    Elixir
  • Created about 3 years ago
  • Updated about 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Req is a batteries-included HTTP client for Elixir.

Req

CI

Docs

Req is a batteries-included HTTP client for Elixir.

With just a couple lines of code:

Mix.install([
  {:req, "~> 0.4.0"}
])

Req.get!("https://api.github.com/repos/wojtekmach/req").body["description"]
#=> "Req is a batteries-included HTTP client for Elixir."

we get automatic response body decompression & decoding, following redirects, retrying on errors, and much more. Virtually all of the features are broken down into individual functions called steps. You can easily re-use and re-arrange built-in steps (see Req.Steps module) and write new ones.

Features

  • An easy to use high-level API: Req.request/1, Req.new/1, Req.get!/2, Req.post!/2, etc.

  • Extensibility via request, response, and error steps.

  • Request body compression and automatic response body decompression (via compress_body, compressed, and decompress_body steps). Supports gzip, brotli, and zstd decompression.

  • Request body encoding and automatic response body decoding (via encode_body and decode_body steps.)

  • Encode params as query string (via put_params step.)

  • Basic, bearer, and .netrc authentication (via auth step.)

  • Range requests (via put_range) step.)

  • Request body streaming (by setting body: enumerable.)

  • Response body streaming (by setting into: fun | collectable.)

  • Follows redirects (via redirect step.)

  • Retries on errors (via retry step.)

  • Raise on 4xx/5xx errors (via handle_http_errors step.)

  • Basic HTTP caching (via cache step.)

  • Setting base URL (via put_base_url step.)

  • Templated request paths (via put_path_params step.)

  • Running against a plug (via put_plug step.)

  • Pluggable adapters. By default, Req uses Finch (via run_finch step.)

Usage

The easiest way to use Req is with Mix.install/2 (requires Elixir v1.12+):

Mix.install([
  {:req, "~> 0.4.0"}
])

Req.get!("https://api.github.com/repos/wojtekmach/req").body["description"]
#=> "Req is a batteries-included HTTP client for Elixir."

If you want to use Req in a Mix project, you can add the above dependency to your mix.exs.

Here's an example POST with JSON data:

iex> Req.post!("https://httpbin.org/post", json: %{x: 1, y: 2}).body["json"]
%{"x" => 1, "y" => 2}

You can stream request body:

iex> stream = Stream.duplicate("foo", 3)
iex> Req.post!("https://httpbin.org/post", body: stream).body["data"]
"foofoofoo"

and stream the response body:

iex> resp = Req.get!("http://httpbin.org/stream/2", into: IO.stream())
# output: {"url": "http://httpbin.org/stream/2", ...}
# output: {"url": "http://httpbin.org/stream/2", ...}
iex> resp.status
200
iex> resp.body
%IO.Stream{}

If you are planning to make several similar requests, you can build up a request struct with desired common options and re-use it:

req = Req.new(base_url: "https://api.github.com")

Req.get!(req, url: "/repos/sneako/finch").body["description"]
#=> "Elixir HTTP client, focused on performance"

Req.get!(req, url: "/repos/elixir-mint/mint").body["description"]
#=> "Functional HTTP client for Elixir with support for HTTP/1 and HTTP/2."

See Req.new/1 for more information on available options.

Virtually all of Req's features are broken down into individual pieces - steps. Req works by running the request struct through these steps. You can easily reuse or rearrange built-in steps or write new ones. Importantly, steps are just regular functions. Here is another example where we append a request step that inspects the URL just before requesting it:

req =
  Req.new(base_url: "https://api.github.com")
  |> Req.Request.append_request_steps(
    debug_url: fn request ->
      IO.inspect(URI.to_string(request.url))
      request
    end
  )

Req.get!(req, url: "/repos/wojtekmach/req").body["description"]
# output: "https://api.github.com/repos/wojtekmach/req"
#=> "Req is a batteries-included HTTP client for Elixir."

Custom steps can be packaged into plugins so that they are even easier to use by others. Here are some examples:

And here is how they can be used:

Mix.install([
  {:req, "~> 0.4.0"},
  {:req_easyhtml, "~> 0.1.0"},
  {:req_s3, "~> 0.1.0"},
  {:req_hex, "~> 0.1.0"},
  {:req_github_oauth, "~> 0.1.0"}
])

req =
  (Req.new(http_errors: :raise)
  |> ReqEasyHTML.attach()
  |> ReqS3.attach()
  |> ReqHex.attach()
  |> ReqGitHubOAuth.attach())

Req.get!(req, url: "https://elixir-lang.org").body[".entry-summary h5"]
#=>
# #EasyHTML[<h5>
#    Elixir is a dynamic, functional language for building scalable and maintainable applications.
#  </h5>]

Req.get!(req, url: "s3://ossci-datasets").body
#=>
# [
#   "mnist/",
#   "mnist/t10k-images-idx3-ubyte.gz",
#   "mnist/t10k-labels-idx1-ubyte.gz",
#   "mnist/train-images-idx3-ubyte.gz",
#   "mnist/train-labels-idx1-ubyte.gz"
# ]

Req.get!(req, url: "https://repo.hex.pm/tarballs/req-0.1.0.tar").body["metadata.config"]["links"]
#=> %{"GitHub" => "https://github.com/wojtekmach/req"}

Req.get!(req, url: "https://api.github.com/user").body["login"]
# output:
# paste this user code:
#
#   6C44-30A8
#
# at:
#
#   https://github.com/login/device
#
# open browser window? [Yn]
# 15:22:28.350 [info] response: authorization_pending
# 15:22:33.519 [info] response: authorization_pending
# 15:22:38.678 [info] response: authorization_pending
#=> "wojtekmach"

Req.get!(req, url: "https://api.github.com/user").body["login"]
#=> "wojtekmach"

See Req.Request module documentation for more information on low-level API, request struct, and developing plugins.

Presentations

Acknowledgments

Req is built on top of Finch and is inspired by cURL, Requests, Tesla, and many other HTTP clients - thank you!

License

Copyright (c) 2021 Wojtek Mach

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

More Repositories

1

acme_bank

An example β˜‚ project
Elixir
748
star
2

mix_install_examples

A collection of simple Elixir scripts that are using Mix.install/2.
Elixir
484
star
3

oop

OOP in Elixir!
Elixir
294
star
4

mini_repo

MiniRepo allows self-hosting of Hex packages.
Elixir
191
star
5

github_ecto

Ecto adapter for GitHub API
Elixir
120
star
6

elixir-run

Erlang/OTP + Elixir + IEx + Mix in a single executable for Linux/macOS/Windows. Just run Elixir!
Elixir
113
star
7

calendar_interval

Functions for working with calendar intervals
Elixir
66
star
8

hello_beam

Elixir, Erlang, Gleam & LFE code all in the same project!
Erlang
64
star
9

phoenix_example

An example Phoenix app with one-click deployments to different cloud services.
Elixir
62
star
10

rubyfmt

Ruby
46
star
11

minitest-capybara

**Deprecated** Capybara matchers support for minitest unit & spec
Ruby
41
star
12

easyhtml

EasyHTML makes it easy to work with HTML in Elixir.
Elixir
39
star
13

minitest-metadata

Annotate tests with key/value metadata
Ruby
36
star
14

openapi

A proof-of-concept for generating OpenAPI clients in Elixir.
Elixir
28
star
15

calendar_recurrence

Recurrence is an Elixir library for working with recurring dates
Elixir
26
star
16

req_easyhtml

Req plugin for EasyHTML.
Elixir
21
star
17

shipit

ShipIt automates Hex package publishing to avoid common mistakes
Elixir
21
star
18

notebooks

A few example Livebook notebooks.
20
star
19

dotfiles

~wojtek
Shell
20
star
20

embedded_record

Embed objects in a bitmask field. Similar to bitmask-attribute and friends
Ruby
17
star
21

attrs

Yet another attributes on steroids gem
Ruby
17
star
22

ets_ecto

Elixir
16
star
23

easyxml

An experimental easy-to-use XML library for Elixir.
Elixir
13
star
24

system_castore

Elixir
9
star
25

value_inspect

Provides implementation of #inspect that is arguably more readable and can be used in irb.
Ruby
9
star
26

que

Elixir
8
star
27

defc

Elixir
8
star
28

mix_gen_callback

Mix task for generating a callback module for a given behaviour
Elixir
8
star
29

app_manifest

Elixir
8
star
30

beamup-old

Shell
8
star
31

system_target

Elixir
7
star
32

docs_chunks

Erlang
7
star
33

openurl

openurl
Elixir
7
star
34

req_s3

Elixir
6
star
35

jsonapi_ecto

Ecto adapter for any JSON API compatible backend
Elixir
6
star
36

req_hex

Elixir
6
star
37

otp_builds

Shell
6
star
38

beamup

Shell
6
star
39

vim-rename

Rename : Rename a buffer within Vim and on disk (by Christian J. Robinson)
Vim Script
6
star
40

backoff

Elixir
5
star
41

spec

Elixir
5
star
42

req_github_oauth

Elixir
5
star
43

unit

Elixir
5
star
44

bitfield

Elixir
5
star
45

fix

Elixir
5
star
46

poker_elixir

An Elixir library to work with Poker hands.
Elixir
5
star
47

nanorepo

Elixir
5
star
48

otp_docs

Shell
5
star
49

poker

Ruby poker library for evaluating hands
C
4
star
50

global_id

Elixir
4
star
51

goth

Elixir
4
star
52

requests

Elixir
3
star
53

fluentx

Elixir
3
star
54

code_info

Elixir
3
star
55

mix_deps_add

Elixir
3
star
56

docker-beam

Dockerfile
3
star
57

kino_req

Elixir
3
star
58

rebar_ex2erl

Erlang
3
star
59

any_value

Collection of helper methods for testing "shape" of the data
Ruby
3
star
60

req_examples

Elixir
2
star
61

fs

Elixir
2
star
62

token_cache

Elixir
2
star
63

objc

Elixir
2
star
64

modulesdiff

Compare modules & functions between versions
Elixir
2
star
65

phoenix_now

Elixir
2
star
66

iex_help_open

Elixir
2
star
67

twirp_elixir

Elixir
2
star
68

hex_tar

Erlang
2
star
69

decimal_eval

Elixir
2
star
70

changelog

Print changelog of a Hex package
Elixir
2
star
71

sigil_z

Handles the ~Z sigil for UTC date times.
Elixir
2
star
72

mix_zig_cc

Elixir
2
star
73

signups

Experimental app showing how one test can be used on many levels: directly using app logic, against Web UI and API.
Ruby
2
star
74

minitest-capybara-example

Example Rails app for https://github.com/wojtekmach/minitest-capybara
Ruby
2
star
75

spdx

SPDX license list for Elixir
Elixir
2
star
76

automigrate

Elixir
1
star
77

macos_examples

Objective-C
1
star
78

dotlocal

Serve your web app as myapp.local with minimal configuration
Elixir
1
star
79

inspect_record

Elixir
1
star
80

playground

Elixir
1
star
81

readmexec

Readmexec grabs commands from your README and runs them.
Ruby
1
star
82

twittr

Experiment
Elixir
1
star
83

exla

Elixir Client for XLA
C++
1
star
84

wx_demo

Elixir
1
star
85

goth_example

Elixir
1
star
86

chatty

Phoenix chat app. Based on: http://www.youtube.com/watch?v=RPs4SHpSThU
Elixir
1
star
87

catd

Polls for changes in some `foo.d/` directory and concatenates all files into one `foo`
Go
1
star
88

foo

Elixir
1
star
89

wx_examples

Elixir
1
star
90

mr-rebase

A bot that rebases PRs
Elixir
1
star
91

open

Elixir
1
star
92

hippy

JavaScript
1
star
93

bandit_mock

Elixir
1
star
94

cmark_native

Elixir
1
star
95

phoenix_dashboard_clock

Elixir
1
star
96

rss

Elixir
1
star
97

slow_ex_unit

Elixir
1
star
98

elixirsh

Elixir
1
star
99

erl_doc_chunks

Erlang
1
star
100

minimal

Elixir
1
star