@@ -7,6 +7,10 @@ use std::{
7
7
use anyhow:: Context ;
8
8
use async_trait:: async_trait;
9
9
use convex_fivetran_common:: config:: Config ;
10
+ use convex_fivetran_source:: api_types:: {
11
+ DocumentDeltasArgs ,
12
+ ListSnapshotArgs ,
13
+ } ;
10
14
use derive_more:: {
11
15
Display ,
12
16
From ,
@@ -16,7 +20,6 @@ use headers::{
16
20
HeaderName ,
17
21
HeaderValue ,
18
22
} ;
19
- use maplit:: btreemap;
20
23
use serde:: {
21
24
de:: DeserializeOwned ,
22
25
Deserialize ,
@@ -68,35 +71,70 @@ pub struct ConvexApi {
68
71
}
69
72
70
73
impl ConvexApi {
71
- /// Performs a GET HTTP request to a given endpoint of the Convex API using
72
- /// the given query parameters.
73
- async fn get < T : DeserializeOwned > (
74
+ /// Performs a GET HTTP request to a given endpoint of the Convex API.
75
+ async fn get < T : DeserializeOwned > ( & self , endpoint : & str ) -> anyhow:: Result < T > {
76
+ let url = self
77
+ . config
78
+ . deploy_url
79
+ . join ( "api/" )
80
+ . unwrap ( )
81
+ . join ( endpoint)
82
+ . unwrap ( ) ;
83
+
84
+ match reqwest:: Client :: new ( )
85
+ . get ( url)
86
+ . header ( CONVEX_CLIENT_HEADER , & * CONVEX_CLIENT_HEADER_VALUE )
87
+ . header (
88
+ reqwest:: header:: AUTHORIZATION ,
89
+ format ! ( "Convex {}" , self . config. deploy_key) ,
90
+ )
91
+ . send ( )
92
+ . await
93
+ {
94
+ Ok ( resp) if resp. status ( ) . is_success ( ) => Ok ( resp
95
+ . json :: < T > ( )
96
+ . await
97
+ . context ( "Failed to deserialize query result" ) ?) ,
98
+ Ok ( resp) => {
99
+ if let Ok ( text) = resp. text ( ) . await {
100
+ anyhow:: bail!(
101
+ "Call to {endpoint} on {} returned an unsuccessful response: {text}" ,
102
+ self . config. deploy_url
103
+ )
104
+ } else {
105
+ anyhow:: bail!(
106
+ "Call to {endpoint} on {} returned no response" ,
107
+ self . config. deploy_url
108
+ )
109
+ }
110
+ } ,
111
+ Err ( e) => anyhow:: bail!( e. to_string( ) ) ,
112
+ }
113
+ }
114
+
115
+ /// Performs a POST HTTP request to a given endpoint of the Convex API using
116
+ /// the given parameters as a JSON body.
117
+ async fn post < P : Serialize , T : DeserializeOwned > (
74
118
& self ,
75
119
endpoint : & str ,
76
- parameters : BTreeMap < & str , Option < String > > ,
120
+ parameters : P ,
77
121
) -> anyhow:: Result < T > {
78
- let non_null_parameters: BTreeMap < & str , String > = parameters
79
- . into_iter ( )
80
- . filter_map ( |( key, value) | value. map ( |value| ( key, value) ) )
81
- . collect ( ) ;
82
-
83
- let mut url = self
122
+ let url = self
84
123
. config
85
124
. deploy_url
86
125
. join ( "api/" )
87
126
. unwrap ( )
88
127
. join ( endpoint)
89
128
. unwrap ( ) ;
90
129
91
- url. query_pairs_mut ( ) . extend_pairs ( non_null_parameters) ;
92
-
93
130
match reqwest:: Client :: new ( )
94
- . get ( url)
131
+ . post ( url)
95
132
. header ( CONVEX_CLIENT_HEADER , & * CONVEX_CLIENT_HEADER_VALUE )
96
133
. header (
97
134
reqwest:: header:: AUTHORIZATION ,
98
135
format ! ( "Convex {}" , self . config. deploy_key) ,
99
136
)
137
+ . json ( & parameters)
100
138
. send ( )
101
139
. await
102
140
{
@@ -125,8 +163,7 @@ impl ConvexApi {
125
163
#[ async_trait]
126
164
impl Source for ConvexApi {
127
165
async fn test_streaming_export_connection ( & self ) -> anyhow:: Result < ( ) > {
128
- self . get ( "test_streaming_export_connection" , btreemap ! { } )
129
- . await
166
+ self . get ( "test_streaming_export_connection" ) . await
130
167
}
131
168
132
169
async fn list_snapshot (
@@ -135,13 +172,14 @@ impl Source for ConvexApi {
135
172
cursor : Option < ListSnapshotCursor > ,
136
173
table_name : Option < String > ,
137
174
) -> anyhow:: Result < ListSnapshotResponse > {
138
- self . get (
175
+ self . post (
139
176
"list_snapshot" ,
140
- btreemap ! {
141
- "snapshot" => snapshot. map( |n| n. to_string( ) ) ,
142
- "cursor" => cursor. map( |n| n. to_string( ) ) ,
143
- "tableName" => table_name,
144
- "format" => Some ( "convex_encoded_json" . to_string( ) ) ,
177
+ ListSnapshotArgs {
178
+ snapshot,
179
+ cursor : cursor. map ( |c| c. into ( ) ) ,
180
+ table_name,
181
+ component : None ,
182
+ format : Some ( "convex_encoded_json" . to_string ( ) ) ,
145
183
} ,
146
184
)
147
185
. await
@@ -152,20 +190,21 @@ impl Source for ConvexApi {
152
190
cursor : DocumentDeltasCursor ,
153
191
table_name : Option < String > ,
154
192
) -> anyhow:: Result < DocumentDeltasResponse > {
155
- self . get (
193
+ self . post (
156
194
"document_deltas" ,
157
- btreemap ! {
158
- "cursor" => Some ( cursor. to_string( ) ) ,
159
- "tableName" => table_name,
160
- "format" => Some ( "convex_encoded_json" . to_string( ) ) ,
195
+ DocumentDeltasArgs {
196
+ cursor : Some ( cursor. into ( ) ) ,
197
+ table_name,
198
+ component : None ,
199
+ format : Some ( "convex_encoded_json" . to_string ( ) ) ,
161
200
} ,
162
201
)
163
202
. await
164
203
}
165
204
166
205
async fn get_tables_and_columns ( & self ) -> anyhow:: Result < BTreeMap < TableName , Vec < FieldName > > > {
167
206
let tables_to_columns: BTreeMap < TableName , Vec < String > > =
168
- self . get ( "get_tables_and_columns" , btreemap ! { } ) . await ?;
207
+ self . get ( "get_tables_and_columns" ) . await ?;
169
208
170
209
tables_to_columns
171
210
. into_iter ( )
0 commit comments