Elixir Tesla 库使用指南:从基础请求到高级功能
概述
Elixir Tesla 是一个功能强大的 HTTP 客户端库,专为 Elixir 语言设计。它提供了简洁的 API 和灵活的中间件系统,使得处理 HTTP 请求变得异常简单。本文将全面介绍 Tesla 的核心功能,帮助开发者快速上手并掌握其高级用法。
基础请求
创建客户端
Tesla 的核心概念是客户端(Client),它封装了请求配置和中间件:
# 创建带有基础URL的客户端
client = Tesla.client([{Tesla.Middleware.BaseUrl, "https://httpbin.org"}])
Tesla.get(client, "/path")
这种方式允许我们预先配置公共设置,然后在多个请求中复用。
支持的所有HTTP方法
Tesla 支持所有标准 HTTP 方法,调用方式直观:
# GET 请求
Tesla.get("https://httpbin.org/get")
# 无返回体的方法
Tesla.head("https://httpbin.org/anything")
Tesla.options("https://httpbin.org/anything")
Tesla.trace("https://httpbin.org/anything")
# 带请求体的方法
Tesla.post("https://httpbin.org/post", "body")
Tesla.put("https://httpbin.org/put", "body")
Tesla.patch("https://httpbin.org/patch", "body")
Tesla.delete("https://httpbin.org/anything")
请求参数处理
查询参数
Tesla 提供了优雅的方式来处理查询参数:
# 生成 GET /path?a=hi&b[]=1&b[]=2&b[]=3
Tesla.get("https://httpbin.org/anything",
query: [a: "hi", b: [1, 2, 3]])
数组参数会自动转换为正确的格式,这在调用许多现代 API 时非常有用。
请求头
设置请求头非常简单:
Tesla.get("https://httpbin.org/headers",
headers: [{"x-api-key", "1"}])
客户端默认请求头
可以在客户端级别设置默认请求头:
client = Tesla.client([
{Tesla.Middleware.Headers, [{"user-agent", "Tesla"}]}
])
这种方式适合设置认证信息等全局头信息。
多部分表单数据
Tesla 提供了强大的多部分表单支持:
alias Tesla.Multipart
mp =
Multipart.new()
|> Multipart.add_content_type_param("charset=utf-8")
|> Multipart.add_field("field1", "foo")
|> Multipart.add_field("field2", "bar",
headers: [{"content-id", "1"}, {"content-type", "text/plain"}]
)
|> Multipart.add_file("test/tesla/multipart_test_file.sh")
|> Multipart.add_file("test/tesla/multipart_test_file.sh", name: "foobar")
|> Multipart.add_file_content("sample file content", "sample.txt")
{:ok, response} = Tesla.post("https://httpbin.org/post", mp)
这个功能特别适合文件上传和复杂表单提交场景。
流式处理
流式请求体
Tesla 支持流式请求体,非常适合处理大数据量:
defmodule ElasticSearch do
def index(records_stream) do
stream = Stream.map(records_stream, fn record -> %{index: [some, data]} end)
Tesla.post(client(), "/_bulk", stream)
end
defp client do
Tesla.client([
{Tesla.Middleware.BaseUrl, "http://localhost:9200"},
Tesla.Middleware.JSON
], {Tesla.Adapter.Finch, name: MyFinch})
end
end
这种方式可以避免内存中加载全部数据,特别适合处理大型数据集。
流式响应体
Tesla 也支持流式接收响应:
defmodule OpenAI do
def client(token) do
middleware = [
{Tesla.Middleware.BaseUrl, "https://api.openai.com/v1"},
{Tesla.Middleware.BearerAuth, token: token},
{Tesla.Middleware.JSON, decode_content_types: ["text/event-stream"]},
{Tesla.Middleware.SSE, only: :data}
]
Tesla.client(middleware, {Tesla.Adapter.Finch, name: MyFinch})
end
def completion(client, prompt) do
data = %{
model: "gpt-3.5-turbo",
messages: [%{role: "user", content: prompt}],
stream: true
}
Tesla.post(client, "/chat/completions", data,
opts: [adapter: [response: :stream]])
end
end
client = OpenAI.new("<token>")
{:ok, env} = OpenAI.completion(client, "What is the meaning of life?")
env.body |> Stream.each(fn chunk -> IO.inspect(chunk) end)
这个功能对于处理服务器推送事件(SSE)或大文件下载特别有用。
中间件系统
Tesla 的中间件系统是其最强大的特性之一,允许开发者自定义请求/响应处理流程。
自定义中间件示例
defmodule Tesla.Middleware.MyCustomMiddleware do
@moduledoc """
自定义中间件示例
这个中间件演示了如何预处理请求和后处理响应
### 选项
- `:option1` - 第一个配置选项
- `:option2` - 第二个配置选项
"""
@behaviour Tesla.Middleware
@impl Tesla.Middleware
def call(env, next, options) do
with %Tesla.Env{} = env <- preprocess(env) do
env
|> Tesla.run(next)
|> postprocess()
end
end
defp preprocess(env) do
# 在这里修改请求环境
env
end
defp postprocess({:ok, env}) do
# 在这里处理成功响应
{:ok, env}
end
def postprocess({:error, reason}) do
# 在这里处理错误
{:error, reason}
end
end
中间件可以用于添加认证、日志记录、错误处理等各种横切关注点。
适配器系统
Tesla 的适配器系统允许开发者替换底层 HTTP 实现。
自定义适配器示例
defmodule Tesla.Adapter.MyCustomAdapter do
@behaviour Tesla.Adapter
@impl Tesla.Adapter
def run(env, opts) do
# 在这里实现自定义HTTP逻辑
# 返回 {:ok, Tesla.Env.t()} | {:error, term()}
end
end
适配器可以基于不同的HTTP库实现,如Hackney、Finch等,或者实现特殊的网络处理逻辑。
最佳实践
- 客户端复用:创建配置好的客户端实例并复用,避免重复配置
- 中间件组合:将常用功能封装为中间件,提高代码复用性
- 错误处理:为关键请求添加适当的错误处理中间件
- 性能考虑:大数据量场景使用流式处理避免内存问题
- 配置管理:将API基础URL等配置放在应用配置中
Tesla 的这些特性使其成为 Elixir 生态中最灵活、最强大的 HTTP 客户端之一,无论是简单的 API 调用还是复杂的 HTTP 交互场景,都能提供优雅的解决方案。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考