spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
56.64k stars 38.14k forks source link

HTTP interface with application/x-ndjson #31163

Closed shinusuresh closed 1 year ago

shinusuresh commented 1 year ago

Spring HTTP interface with application/x-ndjson Content-type is not creating a new line delimited JSON in the request body.

  @PostExchange(contentType = MediaType.APPLICATION_NDJSON_VALUE)
  ResponseEntity<String> upload(@RequestBody Map<String, String>... data);

The request body is generated as

[{\"1\":\"name\",\"2\":\"name\"}]

Mockserver request log

  {
    "method" : "POST",
    "path" : "/",
    "headers" : {
      "user-agent" : [ "ReactorNetty/1.1.10" ],
      "host" : [ "localhost:8787" ],
      "content-length" : [ "25" ],
      "accept-encoding" : [ "gzip" ],
      "accept" : [ "*/*" ],
      "Content-Type" : [ "application/x-ndjson" ]
    },
    "keepAlive" : true,
    "secure" : false,
    "protocol" : "HTTP_1_1",
    "localAddress" : "127.0.0.1:8787",
    "remoteAddress" : "127.0.0.1:50897",
    "body" : "[{\"1\":\"name\",\"2\":\"name\"}]"
  }

https://github.com/shinusuresh/httpinterface-ndjson

Question in SO - https://stackoverflow.com/questions/76976273/spring-http-interface-ndjson-support

rstoyanchev commented 1 year ago

This is unrelated to the HTTP Interface client, and using WebClient directly should give the same result. NDJSON is a streaming format, and we support that with a Flux for the request body. I'm not sure what your intent is but a Map is written as any other single value and there is no streaming involved in that.

shinusuresh commented 1 year ago

Thanks, @rstoyanchev for checking this. I was expecting an input of

Map.of("id", "123")
Map.of("id", "345")

to have a body

{"id": "123"}
{"id": "345"}

May be I misconceive this.

rstoyanchev commented 1 year ago

As ndjson implies a stream, currently we expect a streaming type, e.g. Flux.just(Map.of("id", "123", Map.of("id", "345")). I do see the point that from a client perspective you may not have a stream to send, but may be it's the only format the server expects. If you could provide more details on the scenario and constraints that would be helpful?

Note that even if we added more ways to provide ndjson, it would be something like List<?> where each element is a map or an object, rather than the Map<String, String> you have in your original code snippet.

spring-projects-issues commented 1 year ago

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

shinusuresh commented 1 year ago

Thank you for checking this. Feel free to close this issue as I was able to achieve it differently than using a varargs of Map

sbrannen commented 1 year ago

Thanks for the feedback, @shinusuresh.

I'll close this issue now.