# http
[![Build Status][gh-actions-badge]][gh-actions]
[![LFE Versions][lfe-badge]][lfe]
[![Erlang Versions][erlang-badge]][versions]
[![Tags][github-tags-badge]][github-tags]
*General purpose data, functions, and utilities for use by LFE HTTP clients, servers, URL-parsers, web frameworks, etc.*
[![Project Logo][logo]][logo-large]
##### Table of Contents
* [Features](#features-)
* [Examples](#examples-)
* [Installation](#installation-)
* [License](#license-)
## Features [↟](#table-of-contents)
* **Binary-first design**: All strings are binaries by default for optimal performance
* **Fluent builder pattern**: Chain operations for readable code
* **Request maps**: `(http.request:new #"GET" "http://example.com")`
* **Response helpers**: `(http.response:ok #"Hello, World!")`, `(http.response:json 200 data)`
* **Smart headers**: Case-insensitive lookups, single-pass conversions
* **Erlang httpc interop**: `(http.c:request "http://google.com")`
* **150+ status codes**: `(http.status:im-a-teapot)`, `(http.status:code->message 200)`
* **2000+ MIME types**: `(http.mimetype:from-extension "json")`
* **Query parameters**: Automatic parsing and reconstruction
* **Content helpers**: `set-json`, `set-form`, `set-text` for common formats
## Examples [↟](#table-of-contents)
### Basic HTTP Client Requests
Start the required applications:
```lfe
(inets:start)
(ssl:start)
```
Simple GET request:
```lfe
> (http.c:request "https://httpbin.org/get")
#(ok #m(status 200
        headers #m(#"Content-Type" #"application/json" ...)
        body #"..."
        version 1.1))
```
GET request with custom headers:
```lfe
> (let* ((req (http.request:new "https://httpbin.org/headers"))
         (req-with-headers (http.request:set-header req #"User-Agent" #"lfe-http/1.0")))
    (http.c:request req-with-headers))
#(ok #m(status 200 ...))
```
POST request with JSON:
```lfe
> (let* ((body #"{\"name\":\"LFE\",\"type\":\"language\"}")
         (req (http.request:new #"POST" "https://httpbin.org/post"))
         (req-with-json (http.request:set-json req body)))
    (http.c:request req-with-json))
#(ok #m(status 200 ...))
```
POST with custom headers and body:
```lfe
> (let* ((headers (http.header:add (http.header:new)
                                    #"Content-Type"
                                    #"application/x-www-form-urlencoded"))
         (body #"key1=value1&key2=value2"))
    (http.c:request #"POST" "https://httpbin.org/post" body headers))
#(ok #m(status 200 ...))
```
### Working with Headers
Create a new headers map:
```lfe
> (http.header:new)
#m()
```
Add headers:
```lfe
> (let* ((h1 (http.header:new))
         (h2 (http.header:add h1 #"Content-Type" #"application/json"))
         (h3 (http.header:add h2 #"Accept" #"application/json")))
    h3)
#m(#"Content-Type" #"application/json"
   #"Accept" #"application/json")
```
Convert from a property list:
```lfe
> (http.header:from-list '(#(#"Content-Type" #"text/plain")
                            #(#"Accept" #"*/*")))
#m(#"Content-Type" #"text/plain"
   #"Accept" #"*/*")
```
Get header values (case-sensitive):
```lfe
> (let ((headers (http.header:from-list '(#(#"Content-Type" #"application/json")))))
    (http.header:get headers #"Content-Type"))
#"application/json"
```
Get header values (case-insensitive):
```lfe
> (let ((headers (http.header:from-list '(#(#"Content-Type" #"application/json")))))
    (http.header:get headers #"content-type" 'undefined #m(case-insensitive true)))
#"application/json"
```
Merge headers:
```lfe
> (let ((h1 (http.header:from-list '(#(#"Accept" #"application/json"))))
        (h2 (http.header:from-list '(#(#"Content-Type" #"text/plain")))))
    (http.header:merge h1 h2))
#m(#"Accept" #"application/json"
   #"Content-Type" #"text/plain")
```
## Installation [↟](#table-of-contents)
Add it to your `rebar.config` deps:
```erlang
{deps, [
  ...
  {http, "1.0.0", {pkg, lfe_http}}
]}.
```
## License [↟](#table-of-contents)
Apache License, Version 2.0
Copyright © 2023-2025, Duncan McGreggor <oubiwann@gmail.com>.
[//]: ---Named-Links---
[logo]: https://avatars1.githubusercontent.com/u/3434967?s=250
[logo-large]: https://avatars1.githubusercontent.com/u/3434967
[gh-actions-badge]: https://github.com/lfex/http/workflows/ci%2Fcd/badge.svg
[gh-actions]: https://github.com/lfex/http/actions
[lfe]: https://github.com/lfe/lfe
[lfe-badge]: https://img.shields.io/badge/lfe-2.2-blue.svg
[erlang-badge]: https://img.shields.io/badge/erlang-24%20to%2028-blue.svg
[versions]: https://github.com/lfex/http/blob/master/.github/workflows/cicd.yml
[github-tags]: https://github.com/lfex/http/tags
[github-tags-badge]: https://img.shields.io/github/tag/lfex/http.svg