core.httpconnection #
HTTPConnection Module
The HTTPConnection module provides a robust HTTP client implementation with support for JSON handling, custom headers, retries, and caching.
Features
- Generic JSON methods for type-safe requests
- Custom header support
- Built-in retry mechanism
- Cache configuration
- URL encoding support
Basic Usage
import freeflowuniverse.herolib.core.httpconnection
// Create a new HTTP connection
mut conn := HTTPConnection{
base_url: 'https://api.example.com'
retry: 5 // number of retries for failed requests
}
important: How to use it on a management class e.g. an installe or a client
// e.g. HetznerManager is the object on which we want to have an http client
pub fn (mut h HetznerManager) connection() !&httpconnection.HTTPConnection {
mut c := h.conn or {
mut c2 := httpconnection.new(
name: 'hetzner_${h.name}'
url: h.baseurl
cache: true
retry: 3
)!
c2.basic_auth(h.user, h.password)
c2
}
return c
}
Examples
GET Request with JSON Response
// Define your data structure
struct User {
id int
name string
email string
}
// Make a GET request and decode JSON response
user := conn.get_json_generic[User](
method: .get
prefix: 'users/1'
dataformat: .urlencoded
)!
GET Request for List of Items
// Get a list of items and decode each one
users := conn.get_json_list_generic[User](
method: .get
prefix: 'users'
list_dict_key: 'users' // if response is wrapped in a key
dataformat: .urlencoded
)!
POST Request with JSON Data
// Create new resource with POST
new_user := conn.post_json_generic[User](
method: .post
prefix: 'users'
dataformat: .urlencoded
params: {
'name': 'John Doe'
'email': 'john@example.com'
}
)!
Real-World Example: SSH Key Management
Here's a practical example inspired by SSH key management in a cloud API:
// Define the SSH key structure
struct SSHKey {
pub mut:
name string
fingerprint string
type_ string @[json: 'type']
size int
created_at string
data string
}
// Get all SSH keys
fn get_ssh_keys(mut conn HTTPConnection) ![]SSHKey {
return conn.get_json_list_generic[SSHKey](
method: .get
prefix: 'key'
list_dict_key: 'key'
dataformat: .urlencoded
)!
}
// Create a new SSH key
fn create_ssh_key(mut conn HTTPConnection, name string, key_data string) !SSHKey {
return conn.post_json_generic[SSHKey](
method: .post
prefix: 'key'
dataformat: .urlencoded
params: {
'name': name
'data': key_data
}
)!
}
// Delete an SSH key
fn delete_ssh_key(mut conn HTTPConnection, fingerprint string) ! {
conn.delete(
method: .delete
prefix:'key/${fingerprint}'
dataformat: .urlencoded
)!
}
Custom Headers
You can set default headers for all requests or specify headers for individual requests:
import net.http { Header }
// Set default headers for all requests
conn.default_header = http.new_header(
key: .authorization
value: 'Bearer your-token-here'
)
// Add custom headers for specific request
response := conn.get_json(
method: .get
prefix: 'protected/resource'
header: http.new_header(
key: .content_type
value: 'application/json'
)
)!
Error Handling
The module uses V's built-in error handling. All methods that can fail return a Result type:
// Handle potential errors
user := conn.get_json_generic[User](
method: .get
prefix: 'users/1'
) or {
println('Error: ${err}')
return
}
Cache Configuration
The module supports caching of responses. Configure caching behavior through the CacheConfig
struct:
mut conn := HTTPConnection{
base_url: 'https://api.example.com'
cache: CacheConfig{
enabled: true
// Add other cache configuration as needed
}
}
fn new #
fn new(args HTTPConnectionArgs) !&HTTPConnection
enum DataFormat #
enum DataFormat {
json // application/json
urlencoded //
multipart_form //
}
struct CacheConfig #
struct CacheConfig {
pub mut:
key string // as used to identity in redis
allowable_methods []Method = [.get, .head]
allowable_codes []int = default_cacheable_codes
disable bool = true // default cache is not working
expire_after int = 3600 // default expire_after is 1h
match_headers bool // cache the request header to be matched later
}
struct HTTPConnection #
struct HTTPConnection {
pub mut:
redis Redis @[str: skip]
base_url string // the base url
default_header Header
cache CacheConfig
retry int = 5
}
fn (HTTPConnection) basic_auth #
fn (mut conn HTTPConnection) basic_auth(username string, password string)
fn (HTTPConnection) cache_drop #
fn (mut h HTTPConnection) cache_drop() !
drop full cache for specific cache_key
fn (HTTPConnection) delete #
fn (mut h HTTPConnection) delete(req_ Request) !string
Delete Request with json data and return response as string
fn (HTTPConnection) delete_json_generic #
fn (mut h HTTPConnection) delete_json_generic[T](req Request) !T
TODO
fn (HTTPConnection) get #
fn (mut h HTTPConnection) get(req_ Request) !string
Get Request with json data and return response as string
fn (HTTPConnection) get_json #
fn (mut h HTTPConnection) get_json(req Request) !string
dict_key string //if the return is a dict, then will take the element out of the dict with the key and process further
fn (HTTPConnection) get_json_dict #
fn (mut h HTTPConnection) get_json_dict(req Request) !map[string]json2.Any
do a request with certain prefix on the already specified url parse as json
fn (HTTPConnection) get_json_generic #
fn (mut h HTTPConnection) get_json_generic[T](req Request) !T
fn (HTTPConnection) get_json_list #
fn (mut h HTTPConnection) get_json_list(req Request) ![]string
dict_key string //if the return is a dict, then will take the element out of the dict with the key and process further list_dict_key string //if the output is a list of dicts, then will process each element of the list to take the val with key out of that dict e.g. the input is a list of dicts e.g. [{"key":{"name":"kristof@incubaid.com",...},{"key":...}]
fn (HTTPConnection) get_json_list_generic #
fn (mut h HTTPConnection) get_json_list_generic[T](req Request) ![]T
fn (HTTPConnection) post_json_generic #
fn (mut h HTTPConnection) post_json_generic[T](req Request) !T
fn (HTTPConnection) post_json_str #
fn (mut h HTTPConnection) post_json_str(req_ Request) !string
dict_key string //if the return is a dict, then will take the element out of the dict with the key and process further
fn (HTTPConnection) post_multi_part #
fn (mut h HTTPConnection) post_multi_part(req Request, form http.PostMultipartFormConfig) !http.Response
performs a multi part form data request
fn (HTTPConnection) put_json_generic #
fn (mut h HTTPConnection) put_json_generic[T](req Request) !T
TODO
fn (HTTPConnection) send #
fn (mut h HTTPConnection) send(req_ Request) !Result
Core fucntion to be used in all other function
struct HTTPConnectionArgs #
struct HTTPConnectionArgs {
pub:
name string @[required]
url string @[required]
cache bool
retry int = 1
}
struct Request #
struct Request {
pub mut:
method Method
prefix string
id string
params map[string]string
data string
cache_disable bool // do not put this default on true, this is set on the connection, this is here to be overruled in specific cases
header ?Header
dict_key string // if the return is a dict, then will take the element out of the dict with the key and process further
list_dict_key string // if the output is a list of dicts, then will process each element of the list to take the val with key out of that dict
debug bool
dataformat DataFormat
}
struct Result #
struct Result {
pub mut:
code int
data string
}
fn (Result) is_ok #
fn (r Result) is_ok() bool