1

I am sending a PATCH request to a server which gives me back a 200 and no body (perfectly acceptable) however I can't work out how to configure the micronaut @Patch annotation to deal with this. No matter what I try it tries to decode the empty response as JSON (at least I think that's what it is doing as it gives an unexpected error rather than the normal jackson error you get when the body is wrong). I can't find anything in the micronaut docs about how to do this.

shmish111
  • 3,697
  • 5
  • 30
  • 52
  • 1
    Can you provide the code sample that illustrates your current attempts? It doesn't have to be exactly the same code (if it contains sensitive data), but something that reproduces the issues with the minimal viable example. – Szymon Stepniak Oct 27 '21 at 10:08
  • There is an example of some uses at https://github.com/micronaut-projects/micronaut-core/blob/f829533d0bf39f97246770b1c709fbffbfbc93d8/http-client/src/test/groovy/io/micronaut/http/client/HttpPatchSpec.groovy#L217-L224. – Jeff Scott Brown Oct 27 '21 at 20:39
  • What is the content type of the response associated with the endpoint you are invoking? – Jeff Scott Brown Oct 28 '21 at 14:19

1 Answers1

0

I am sending a PATCH request to a server which gives me back a 200 and no body (perfectly acceptable) however I can't work out how to configure the micronaut @Patch annotation to deal with this

I think this will work with @Patch the same way it does with other verbs.

See the project at https://github.com/jeffbrown/patchwithemptyresponse.

server/src/main/java/server/DemoController.java

package server;

import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Patch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Controller("/demo")
public class DemoController {
    static final Logger log = LoggerFactory.getLogger(DemoController.class);

    @Patch
    HttpResponse doSomething() {
        log.info("Returning an empty response with status code 200");
        return HttpResponse.ok();
    }
}

client/src/main/java/client/DemoClient.java

package client;

import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Patch;
import io.micronaut.http.client.annotation.Client;

@Client("http://localhost:8080")
public interface DemoClient {

    @Patch("/demo")
    HttpResponse callServer();
}

client/src/main/java/client/ClientCommand.java

package client;

import io.micronaut.configuration.picocli.PicocliRunner;
import io.micronaut.context.ApplicationContext;

import jakarta.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

@Command(name = "client", description = "...",
        mixinStandardHelpOptions = true)
public class ClientCommand implements Runnable {

    static final Logger log = LoggerFactory.getLogger(ClientCommand.class);

    @Inject
    DemoClient client;

    public static void main(String[] args) throws Exception {
        PicocliRunner.run(ClientCommand.class, args);
    }

    public void run() {
        log.info("Before calling server.");
        client.callServer();
        log.info("After calling server");
    }
}

If you run the server you can then run the client and see a successful round trip with an empty body.

~ $ git clone git@github.com:jeffbrown/patchwithemptyresponse.git
Cloning into 'patchwithemptyresponse'...
remote: Enumerating objects: 51, done.
remote: Counting objects: 100% (51/51), done.
remote: Compressing objects: 100% (31/31), done.
remote: Total 51 (delta 4), reused 51 (delta 4), pack-reused 0
Receiving objects: 100% (51/51), 65.64 KiB | 1.04 MiB/s, done.
Resolving deltas: 100% (4/4), done.

Run the server:

~ $ cd patchwithemptyresponse 
patchwithemptyresponse (main)$ ./gradlew server:run

> Task :server:compileJava
Note: Creating bean classes for 1 type elements

> Task :server:run
 __  __ _                                  _   
|  \/  (_) ___ _ __ ___  _ __   __ _ _   _| |_ 
| |\/| | |/ __| '__/ _ \| '_ \ / _` | | | | __|
| |  | | | (__| | | (_) | | | | (_| | |_| | |_ 
|_|  |_|_|\___|_|  \___/|_| |_|\__,_|\__,_|\__|
  Micronaut (v3.1.0)

18:17:56.201 [main] INFO  io.micronaut.runtime.Micronaut - Startup completed in 748ms. Server Running: http://localhost:8080

Run the client:

~ $ cd patchwithemptyresponse 
patchwithemptyresponse (main)$ 
patchwithemptyresponse (main)$ ./gradlew client:run
Starting a Gradle Daemon, 1 busy and 1 incompatible and 1 stopped Daemons could not be reused, use --status for details

> Task :client:compileJava
Note: Creating bean classes for 2 type elements

> Task :client:run
18:18:34.618 [main] INFO  i.m.context.env.DefaultEnvironment - Established active environments: [cli]
18:18:34.908 [main] INFO  client.ClientCommand - Before calling server.
18:18:35.680 [main] INFO  client.ClientCommand - After calling server
Jeff Scott Brown
  • 26,804
  • 2
  • 30
  • 47