module client import net.http { Method } import net.urllib import web.response { Response, new_data_response } import json pub struct Client { pub: address string api_key string } // new creates a new Client instance. pub fn new(address string, api_key string) Client { return Client{ address: address api_key: api_key } } // send_request_raw sends an HTTP request, returning the http.Response object. // It encodes the params so that they're safe to pass as HTTP query parameters. fn (c &Client) send_request_raw(method Method, url string, params map[string]string, body string) !http.Response { mut full_url := '$c.address$url' if params.len > 0 { mut params_escaped := map[string]string{} // Escape each query param for k, v in params { // An empty parameter should be the same as not providing it at all params_escaped[k] = urllib.query_escape(v) } params_str := params_escaped.keys().map('$it=${params_escaped[it]}').join('&') full_url = '$full_url?$params_str' } // Looking at the source code, this function doesn't actually fail, so I'm // not sure why it returns an optional mut req := http.new_request(method, full_url, body) or { return error('') } req.add_custom_header('X-Api-Key', c.api_key)! res := req.do()! return res } // send_request just calls send_request_with_body with an empty body. fn (c &Client) send_request(method Method, url string, params map[string]string) !Response { return c.send_request_with_body(method, url, params, '') } // send_request_with_body calls send_request_raw_response & parses its // output as a Response object. fn (c &Client) send_request_with_body(method Method, url string, params map[string]string, body string) !Response { res := c.send_request_raw(method, url, params, body)! status := res.status() // Non-successful requests are expected to return either an empty body or // Response if status.is_error() { // A non-successful status call will have an empty body if res.body == '' { return error('Error $res.status_code ($status.str()): (empty response)') } data := json.decode(Response, res.body)! return error('Status $res.status_code ($status.str()): $data.message') } // Just return an empty successful response if res.body == '' { return new_data_response(T{}) } data := json.decode(Response, res.body)! return data } // send_request_raw_response returns the raw text response for an HTTP request. fn (c &Client) send_request_raw_response(method Method, url string, params map[string]string, body string) !string { res := c.send_request_raw(method, url, params, body)! return res.body }