-
Notifications
You must be signed in to change notification settings - Fork 304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add multipart request support #430
Conversation
cc @bclozel |
Would you like to give any feedback ? |
Sorry we didn't have time to have a deeper look. This is on our radar and we'll let you know once the entire team is back. |
I can rebase it onto Any fixes, any explanations, let me know if they are needed. |
For full transparency, we've discussed this today and we've scheduled this issue (and #69) to the 1.1 Backlog. We don't think we'll get to it in time for 1.1.0, but this is definitely on our radar. Our existing 1.1 milestones are already quite full and we want to make sure we get this right. We'd like to spend more time experimenting with this and thinking about ways to address CSRF issues in general. We might evolve this PR, or selectively pick things up from it. In any case, your contribution will be recognized as it should. |
Is there any update/eta on this? I see the issue itself is on the 1.2 backlog now that doesn't specify any due date or something. |
Can we add it to one of 1.2.x milestones ? @bclozel @rstoyanchev |
@nkonev apologies for the delay in getting back to you. We've discussed this on the team, and think that file uploads embedded in GraphQL requests adds unnecessary complexity vs using an HTTP endpoint to handle multipart requests. A Looking at Apollo Server File Upload Best Practices it seems they've evolved their approach, also moving away from the file uploads spec. The article recommends against using file uploads in strong terms, and suggests to separate handling of file uploads from the handling of GraphQL requests for a variety of reasons including security and performance. Noting what Apollo has done from 3.0 to keep the |
@rstoyanchev thank you for the explanation and link |
As per my last comment, we are not going to have multipart uploads support built in, but I want to make sure there is enough flexibility so it can exist independently. Looking at the PR as a model, on the server side there can be a separate multipart handler that creates a request and passes it down the chain. On the client side, it seems to come down to a slightly customized Overall, the code could become simpler if built more explicitly for HTTP, and separate from the main API vs trying to fit into a transport agnostic base. It also connects back to the mismatch between GraphQL being transport agnostic vs multipart uploads being an HTTP only mechanism, and if you must implement the spec, might as well model it more explicitly along those lines. |
@rstoyanchev public WebGraphQlRequest(...
super(getKey("query", body), getKey("operationName", body), getKey("variables", body),
getKey("extensions", body), id, locale); Are you ok to add one more constructor in separate PR ? To make it simpler to write Multipart GraphQlHttpHandler (than here - see MultipartGraphQlRequest - it will gone if we add the that constructor) public WebGraphQlRequest(
URI uri, HttpHeaders headers,
String query,
String operationName,
Map<String, Object> variables,
Map<String, Object> extensions,
String id, @Nullable Locale locale) {
super(query, operationName, variables, extensions, id, locale);
Assert.notNull(uri, "URI is required'");
Assert.notNull(headers, "HttpHeaders is required'");
this.uri = UriComponentsBuilder.fromUri(uri).build(true);
this.headers = headers;
} About client. It's interesting - to just customize WebClient. Indeed, at first glance it looks attractive, because the only meaningful thing is @Override
public Mono<GraphQlResponse> executeFileUpload(GraphQlRequest request) {
return this.webClient.post()
.contentType(MediaType.MULTIPART_FORM_DATA)
.accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_GRAPHQL)
.body(BodyInserters.fromMultipartData(convertRequestToMultipartData(request)))
.retrieve()
.bodyToMono(MAP_TYPE)
.map(ResponseMapGraphQlResponse::new);
} |
@nkonev sending another PR with concrete suggestions sounds good. |
Closing this for now as we don't intend to proceed as per my earlier #430 (comment). @nkonev, thanks for all the effort in any case! |
Yes, |
There is no way to delete a pull request. Is that what you meant? It's just in "closed" instead of "open" state, but it's still possible to search and find. |
This PR adds MultipartFile support for WebMVC and FilePart for WebFlux on server side, HttpGraphQlClient, HttpGraphQlTester support on client side.
#69
Test project https://github.com/nkonev/graphql.demo/tree/file-test-harness
@rstoyanchev Please take a look when you get a chance.
P. S. About formatting:
I tried to fix it by installing spring-javaformat 034 jar (as described here https://github.com/spring-io/spring-javaformat), but it reports issues of files out of scope my PR. Can you please apply your configured formatter ?
P. S. S. The next step is to add handlers and coercing(optionally) to Spring Boot.