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. *)