Swagger TypeError: Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body
Asked Answered
T

13

111

I have added Swagger to my Spring Boot 2 application:

This is my Swagger config:

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket api() {
        // @formatter:off
        return new Docket(DocumentationType.SWAGGER_2)  
                .select()                                  
                .apis(RequestHandlerSelectors.any())              
                .paths(PathSelectors.any())                          
                .build();
        // @formatter:on
    }
}

This is Maven dependency:

<!-- Swagger2 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.8.0</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.8.0</version>
</dependency>

When I try to invoke for example http://localhost:8080/api/actuator/auditevents it fails with the following error:

TypeError: Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body.

enter image description here

What am I doing wrong and how to fix it ?

Tantara answered 12/2, 2018 at 14:56 Comment(4)
did you fix it?Citrus
any solution for this?Blais
any news about it ?Gibbsite
This is a known bug. Happily someone posted a workaround in the ticket comments.Particularity
C
63

I ran into this issue. Here is how I resolved it:

I had a method like this:

[HttpGet]
public IEnumerable<MyObject> Get(MyObject dto)
{
      ...
}

and I was getting the error. I believe swagger UI is interpreting the Get parameters as FromBody, so it uses the curl -d flag. I added the [FromQuery] decorator and the problem was resolved:

[HttpGet]
public IEnumerable<MyObject> Get([FromQuery]MyObject dto)
{
      ...
}

FYI this also changes the UI experience for that method. instead of supplying json, you will have a form field for each property of the parameter object.

Codicodices answered 23/7, 2019 at 19:13 Comment(2)
Perfect answer!Dermoid
This worked! I don't know why the OP did not mark this an the correct answer.Bozovich
C
56

The error message actually says what the problem is. You post data with curl using the -d option while trying to use GET.

If you use the -d option curl will do POST.
If you use -X GET option curl will do GET.

The HTTP GET method is for requesting a representation of the specified resource. Requests using GET should only retrieve data and hence cannot have body.

More info on GET vs POST

Constancy answered 12/2, 2018 at 17:47 Comment(13)
Thanks for your answer. I'm not using the curl directly. This is some internal output from Swagger 2.8.0. By the way - I have downgraded the Swagger version to 2.7.0 and the issue is gone. What may be wrong with Swagger 2.8.0?Tantara
I see, maybe this is the Swagger issue?Constancy
I am using 2.7.0 as well without any issues. Probably this is an issue what @Constancy mentioned above.Enervate
but he is using swagger ui, not curlCitrus
@Constancy In the link you've provided it does not say that it's impossible to use GET and body at same time. Http specification allows that and thus this topic is about swagger issue (swagger does not implement http properly)Ingmar
For future visitors I was getting this as well using the ruby gem 'rswag' to setup swagger docs. To piggie back off the above answer, I fixed it by changing how the parameter is passed in using a different parameter method. There was one for body params and one for url params. I just had to change a piece from in: :body to in: :path.Ludly
@Constancy I disagree with your answer. Because curl -d also known as --data flag does not care and yes you can pass data to it and yes it does work even on GET requests for example: curl -X GET "https://veggies.com/carrots" -H "Content-Type: application/json" -d "{\"bunny_id\": 22 }". Works perfectly for me because the API supports it and curl also does!. Now for the question of whether it is common or if we should do it that way is another story. curl has no issues with it in any case. I tried it. so the problem must be swagger's fetch function/method not curl -dCalaboose
@Constancy also see: https://mcmap.net/q/40417/-http-get-with-request-bodyCalaboose
@Ludly changing in: :body to in: :query also works! using the rswag ruby gemCalaboose
The body could have information about what kind of data the user wants. I don't the that is a contradiction.Nurseryman
@Sören see GET - HTTP: "Sending body/payload in a GET request may cause some existing implementations to reject the request — while not prohibited by the specification, the semantics are undefined. It is better to just avoid sending payloads in GET requests."Constancy
@Constancy this has been changed to accept a body in a Get request, or at least the specification hasFinegrain
@NickTurner can you share a link please?Constancy
K
11

I had same problem with my .net core 2.0 solution and GET method that takes element id as header key or search for it by parameters in body. That is not the best way to implement but it's kind of special case.

As mentioned in this discussion. The HTTP spec does not forbid using body on a GET, but swagger is not implementing it like this. Even if there are APIs that work fine with body in GET Requests.

What more, the swagger frontend adds this body object into request even if it is null/undefined/empty object. It is -d "body_content_here" parameter. So in my case when i only search by id and body is empty, it still sends empty object (-d "{}") and throws mentioned error.

Possible solutions:

  • Start using postman app for this request - It will work fine. Tested.

  • Consider moving more advanced GET request (like search with criteria) to the independent POST Method

  • Use swagger generated CURL request request without -d parameter

Kittiekittiwake answered 22/11, 2018 at 15:2 Comment(1)
CURL works fine when using the -d parameter as tested on Ubuntu with version 7.68. It is really Swagger that does not support GET request with body.Liable
F
5

Don't pass method type in Get method.

let res = await fetch("http://localhost:8080/employee_async",{
                method: "POST",
                body:JSON.stringify(data),
                mode:"cors",
                headers: {"Content-type":"application/json;charset=utf-8"}})

This is used for post only, If we don't assign any method type node automatically considered as Get method

Frenzy answered 5/9, 2018 at 17:3 Comment(1)
Welcome to Stackoverflow. Try to format your code properly as described herePneumococcus
S
5

To avoid this error be sure to annotate parameters in your controller with @RequestParam, like

@GetMapping("/get")
public Response getData(@RequestParam String param)
Subir answered 25/10, 2019 at 15:52 Comment(0)
G
2

Looking at swagger exception/error message , looks like you are calling Get method with a set of input body. As per documentation of GET method doesn't accept any body. You need to change the GET method to POST method. It should work.

Gladiatorial answered 19/9, 2019 at 15:6 Comment(3)
Please provide the link to the source where you read that. Because in fact, the official specification allows the GET method to have the body.Parfait
POST is used to create a new entity in the existing entity set.... A GET method accepting multiple input criteria can be issue when using query strings when the text associated with the input gets longer than URL limit..Gothart
@Gladiatorial could you either provide a source for this, or correct this?Rouen
W
1

I faced similar issue; now, it's resolved. You cannot pass parameter to HTTPGET thru Body. To pass parameter to HTTPGet, there are 2 ways either use [FromRoute] or [FromQuery].

If u use [FromRoute], then

[HttpGet("{param1}/{param2}")]        
public Person Get([FromRoute]string param1, string param2)
{
}

For PersonController, from client side your url should be: http://localhost:000/api/person/value1/value2

If u want to use [FromQuery]

[HttpGet]        
public Person Get([FromQuery]string param1, string param2)
{
}

from client side your url should be: http://localhost:000/api/person?param1=value1&param2=value2

Wulfe answered 18/11, 2022 at 19:34 Comment(0)
I
0

Maybe the problem is with the mapping of the method, make sure to use @RequestMapping(value = "/<your path>" , method = RequestMethod.POST) and put the data as body with @RequestBody

Ist answered 15/11, 2018 at 12:59 Comment(0)
H
0

I also got the same error on the Swagger UI. My problem was I have mistakenly marked the Api Method as GET and send data in the request body. Once I change the annotation @GET to @POST issue got resolved.

Henke answered 20/12, 2018 at 4:28 Comment(0)
S
0

Because you used GET http method with body. If you want to have Json body, etc you need to use POST http method, For example in your controller class, top of your method:

    @PostMapping(value = "/save")
    public ResponseEntity<HttpStatus> savePerson(@RequestBody Person person) 
    {...}

Use GET without body.

Shrivel answered 19/10, 2020 at 15:53 Comment(0)
H
0

Pass Paremeters with [FromQuery] in Methods InPut

Housebreak answered 3/2, 2021 at 11:31 Comment(2)
From Review: Hi, this post does not seem to provide a quality answer to the question. Please either edit your answer and improve it, or just post it as a comment to the question/other answer.Fisken
I confirm that this works...however, I want to be able to use the body for GET request in swagger if possible.Emotive
N
0

I was having this issue when trying to use Swagger UI on a Ruby On Rails app. I fixed it by changing the information container on the curl command. This is a example line:

parameter name: :body, in: :body, schema: {'$ref' => '#/definitions/ActivitiesFilter'}, required: true

into

parameter name: :attribute_name1, in: :query, required: true
parameter name: :attribute_name2, in: :query, required: true
parameter name: :attribute_name3, in: :query, required: true

note that you have to add as many lines as attributes are defined on your schema inside swagger_helper

Neuropath answered 9/6, 2021 at 16:44 Comment(0)
C
0

This errors happens with wrong argument type. Just change "[FromBody]" to "[FromQuery]".

Caesaria answered 4/7, 2022 at 7:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.