clients.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.crystallib.clients.httpconnection
// Create a new HTTP connection
mut conn := HTTPConnection{
base_url: 'https://api.example.com'
retry: 5 // number of retries for failed requests
}
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
)!
}
fn new #
fn new(args HTTPConnectionArgs) !&HTTPConnection
fn new_request #
fn new_request(args_ Request) !&Request
/ Creates a new HTTP request with the specified parameters. / / This function takes a Request
object and modifies it based on the provided / data format (json
, urlencoded
, or multipart_form
). If the method is POST, / and the data
field is empty but params
is provided, it will encode the params
/ as form data. The corresponding Content-Type
header is set based on the data format. / / # Arguments / / - args
: A Request
object containing the details of the request (method, data, params, etc.). / / # Returns / / - A reference to the modified Request
object.
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) 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) 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