My agentic slop goes here. Not intended for anyone else!
1(** JSON API Helpers for Requests 2 3 This module provides high-level combinators for working with JSON APIs, 4 reducing boilerplate when building API clients. 5 6 {2 Example Usage} 7 8 {[ 9 open Requests_json_api 10 11 let fetch_users session = 12 get_json_exn session (base_url / "users") parse_users 13 ]} 14*) 15 16(** {1 JSON Request Helpers} *) 17 18val get_json_exn : (_ Eio.Time.clock, _ Eio.Net.t) Requests.t -> string -> (Ezjsonm.value -> 'a) -> 'a 19(** [get_json_exn session url parser] makes a GET request, checks status is 2xx, 20 reads and parses JSON body, then applies the parser function. 21 Raises [Failure] on any error (HTTP, network, or JSON parse). *) 22 23val get_json : (_ Eio.Time.clock, _ Eio.Net.t) Requests.t -> string -> (Ezjsonm.value -> 'a) -> 24 ('a, [> `Http of int * string | `Json_error of string]) result 25(** Like [get_json_exn] but returns [Result] instead of raising exceptions. 26 Returns [Ok parsed_value] on success, or [Error] with details on failure. *) 27 28val post_json : (_ Eio.Time.clock, _ Eio.Net.t) Requests.t -> string -> Ezjsonm.value -> Requests.Response.t 29(** [post_json session url json_value] creates a JSON request body and POSTs it to the URL. 30 Returns the raw response for custom handling. *) 31 32val post_json_exn : (_ Eio.Time.clock, _ Eio.Net.t) Requests.t -> string -> Ezjsonm.value -> string 33(** Like [post_json] but checks status is 2xx and returns the response body as a string. 34 Raises [Failure] on non-2xx status. *) 35 36val post_json_result : (_ Eio.Time.clock, _ Eio.Net.t) Requests.t -> string -> Ezjsonm.value -> 37 (string, int * string) result 38(** Like [post_json_exn] but returns [Result] instead of raising. 39 [Ok body] on 2xx status, [Error (status, body)] otherwise. *) 40 41(** {1 JSON Parsing Helpers} *) 42 43val parse_json : (Ezjsonm.value -> 'a) -> string -> 'a 44(** [parse_json parser body_str] parses a JSON string and applies the parser function. 45 Raises exception on parse error. *) 46 47val parse_json_result : (Ezjsonm.value -> 'a) -> string -> ('a, string) result 48(** Like [parse_json] but returns [Result] on parse error instead of raising. *) 49 50(** {1 Low-Level Helpers} *) 51 52val read_body : Requests.Response.t -> string 53(** [read_body response] reads the entire response body as a string. 54 Equivalent to [Requests.Response.body response |> Eio.Flow.read_all] *) 55 56val get_result : (_ Eio.Time.clock, _ Eio.Net.t) Requests.t -> string -> (string, int * string) result 57(** [get_result session url] makes a GET request and returns the result. 58 Returns [Ok body] on 2xx status, [Error (status, body)] otherwise. *) 59 60val check_2xx : Requests.Response.t -> (string, int * string) result 61(** [check_2xx response] checks if the response status is 2xx. 62 Returns [Ok body] if status is 2xx, [Error (status, body)] otherwise. *) 63 64val check_ok : Requests.Response.t -> (string, int * string) result 65(** [check_ok response] checks if the response status is exactly 200. 66 Returns [Ok body] if status is 200, [Error (status, body)] otherwise. *) 67 68(** {1 URL Helpers} *) 69 70val ( / ) : string -> string -> string 71(** [base_url / path] joins base URL and path, handling trailing/leading slashes. 72 73 Example: ["https://api.com" / "users" / "123" = "https://api.com/users/123"] *) 74 75val make_url : string -> string -> string 76(** [make_url base_url path] is the function form of the [/] operator. *) 77 78(** {1 Result Composition} *) 79 80module Syntax : sig 81 val ( let* ) : ('a, 'e) result -> ('a -> ('b, 'e) result) -> ('b, 'e) result 82 (** Result bind operator for chaining operations *) 83 84 val ( let+ ) : ('a, 'e) result -> ('a -> 'b) -> ('b, 'e) result 85 (** Result map operator *) 86 87 val ( and* ) : ('a, 'e) result -> ('b, 'e) result -> ('a * 'b, 'e) result 88 (** Result product for parallel operations *) 89 90 val ( and+ ) : ('a, 'e) result -> ('b, 'e) result -> ('a * 'b, 'e) result 91 (** Result product for parallel operations (alias) *) 92end 93 94(** {1 Error Handling} *) 95 96val or_fail : ('a, [< `Http of int * string | `Json_error of string]) result -> 'a 97(** [or_fail result] unwraps a [Result] or raises [Failure] with an error message. 98 Useful for converting Result-based APIs to exception-based code. *) 99 100val or_fail_with : string -> ('a, [< `Http of int * string | `Json_error of string]) result -> 'a 101(** Like [or_fail] but prepends a custom error prefix to the failure message. *)