1212import java .util .Arrays ;
1313import java .util .Collections ;
1414import java .util .List ;
15+ import java .util .function .IntFunction ;
1516import lombok .Getter ;
1617import lombok .NonNull ;
1718import org .springframework .beans .factory .annotation .Value ;
@@ -313,24 +314,36 @@ public GraphQLResponse postMultipart(String query, String variables) {
313314 * will be a part of multipart request. GraphQL Servlet will use <i>map</i> part to walk through
314315 * variables.files and validate the request in combination with other binary file parts
315316 *
316- * <p>-------------- request beginning ---------------
317+ * <p>----------------------------dummyid
317318 *
318- * <p>operations: { "query": "mutation($files:[Upload]!) {uploadFiles(files:$files)}",
319- * "operationName": "uploadFiles", "variables": { "files": [null, null] } }
319+ * <p>Content-Disposition: form-data; name="operations"
320320 *
321- * <p>-----------------------------------------------
321+ * <p>{ "query": "mutation($files:[Upload]!) {uploadFiles(files:$files)}", "operationName":
322+ * "uploadFiles", "variables": { "files": [null, null] } }
323+ *
324+ * <p>----------------------------dummyid
325+ *
326+ * <p>Content-Disposition: form-data; name="map"
322327 *
323328 * <p>map: { "1":["variables.files.0"], "2":["variables.files.1"] }
324329 *
325- * <p>-----------------------------------------------
330+ * <p>----------------------------dummyid
331+ *
332+ * <p>Content-Disposition: form-data; name="1"; filename="file1.pdf"
333+ *
334+ * <p>Content-Type: application/octet-stream
335+ *
336+ * <p>--file 1 binary code--
337+ *
338+ * <p>----------------------------dummyid
326339 *
327- * <p>1: --file 1 binary code--
340+ * <p>Content-Disposition: form-data; name="2"; filename="file2.pdf"
328341 *
329- * <p>-----------------------------------------------
342+ * <p>Content-Type: application/octet-stream
330343 *
331344 * <p>2: --file 2 binary code--
332345 *
333- * <p>-------------- request end ---------------------
346+ * <p>
334347 *
335348 * @param graphqlResource path to the classpath resource containing the GraphQL query
336349 * @param variables the input variables for the GraphQL query
@@ -344,12 +357,39 @@ public GraphQLResponse postFiles(
344357 String graphqlResource , ObjectNode variables , List <ClassPathResource > files )
345358 throws IOException {
346359
360+ return postFiles (
361+ graphqlResource , variables , files , index -> String .format ("variables.files.%d" , index ));
362+ }
363+
364+ /**
365+ * Handle the multipart files upload request to GraphQL servlet
366+ *
367+ * @param graphqlResource path to the classpath resource containing the GraphQL query
368+ * @param variables the input variables for the GraphQL query
369+ * @param files ClassPathResource instance for each file that will be uploaded to GraphQL server.
370+ * When Spring RestTemplate processes the request, it will automatically produce a valid part
371+ * representing given file inside multipart request (including size, submittedFileName, etc.)
372+ * @param pathFunc function to generate the path to file inside variables. For example:
373+ * <ul>
374+ * <li>index -> String.format("variables.files.%d", index) for multiple files
375+ * <li>index -> "variables.file" for single file
376+ * </ul>
377+ *
378+ * @return {@link GraphQLResponse} containing the result of query execution
379+ * @throws IOException if the resource cannot be loaded from the classpath
380+ */
381+ public GraphQLResponse postFiles (
382+ String graphqlResource ,
383+ ObjectNode variables ,
384+ List <ClassPathResource > files ,
385+ IntFunction <String > pathFunc )
386+ throws IOException {
347387 MultiValueMap <String , Object > values = new LinkedMultiValueMap <>();
348388 MultiValueMap <String , Object > map = new LinkedMultiValueMap <>();
349389
350390 for (int i = 0 ; i < files .size (); i ++) {
351391 String valueKey = String .valueOf (i + 1 ); // map value and part index starts at 1
352- map .add (valueKey , String . format ( "variables.files.%d" , i ));
392+ map .add (valueKey , pathFunc . apply ( i ));
353393
354394 values .add (valueKey , files .get (i ));
355395 }
0 commit comments