How do you specify that an API method has no response body? - retrofit

I am trying to use Retrofit 2.0 and the converter-jackson module to consume an API.
I have a few GET methods to get the status of some objects and converting the received payload into the objects works fine.
I also have an endpoint that I need to PUT to in order to acknowledge that I have processed the objects returned to the GET request. This PUT method does not return a body, just a status of 200 if everything works or an appropriate error code.
I have tried a few different ways to specify the put method in my Retrofit interface with no success. I get an error like this:
com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
at [Source: java.io.InputStreamReader#1d5ef9ae; line: 1, column: 1]
if I specify the return type of the method as some object that I don't really expect to receive, like this:
#PUT('/acknowledgeStatus')
Call<String> acknowledgeStatus(#Body Acknowledgement idsToAcknowledge)
and I get errors like this:
java.lang.IllegalArgumentException: Could not locate call adapter for class com.example.MyObject. Tried:
* retrofit.DefaultCallAdapter$1
where MyObject is the object returned by one of my Retrofit API's other GET methods when I try to define the PUT method like either of these:
#PUT('/acknowledgeStatus')
Call acknowledgeStatus(#Body Acknowledgement idsToAcknowledge)
#PUT('/acknowledgeStatus')
Response acknowledgeStatus(#Body Acknowledgement idsToAcknowledge)
How can tell Retrofit not to expect a response body for this method and still have access to the response status, headers and other details?

Update: As of the second beta release, you can use the return type of Void
#PUT('/acknowledgeStatus')
Call<Void> acknowledgeStatus(#Body Acknowledgement idsToAcknowledge)
The following still works, but might be less efficient --
Try telling it you want a ResponseBody.
#PUT('/acknowledgeStatus')
Call<ResponseBody> acknowledgeStatus(#Body Acknowledgement idsToAcknowledge)
that will give you access to the response status, etc, and the raw response body (if any).

Related

akka grpc server stream cannot return every result in real time

First of all, I have a server stream method. In the method, I will request an actor in a loop. I expect that after each request is responded, the application will return the result to the caller. But no, I found that it still waits for all responses to be completed before returning, is this normal?
// The code is as follows, for the convenience of observing the results, I added sleep
override def itKeepsReplying(in: HelloRequest): Source[HelloReply, NotUsed] = {
Source(1 to 10).map(index => {
Thread.sleep(5000)
HelloReply(character.toString)
})
}
In order to confirm whether grpc itself supports, I tried java's implementation of this piece,
If you want to send data to the caller: responseObserver.onNext(responseBuilder.build());,
If you want to end this call: responseObserver.onCompleted(); ,
Data is sent to the caller every time onNext is called.
So my question is:
Is my assumption correct? If akka-grpc can do it
If it can be done, please give an example

How GRPC handle pointer that appear more then once?

For example (golang):
type {
Product struct {
Name string
}
Customer struct {
Name string
Products []*Product
}
}
Which is the correct behavior:
GRPC honor the *Product pointer and transfer it only once.
GRPC will transfer the same *Product as many times as it associated to different Customer.
Michael,
It is not clear on your message, but I am assuming that you will send a Customer as part of your request to a gRPC server.
Golang will marshal the struct into []byte (https://godoc.org/github.com/golang/protobuf/proto#Marshal), so the message will not have such thing as a pointer. It will be just an encoded message. (see
https://github.com/golang/protobuf/blob/master/proto/wire.go#L22).
gRPC is not a Golang thing, so a pointer on a side (e.g. server) does not mean it must be a point on the other side (e.g. client).
Finally, answering your question, the expected behavior is 2. However, you may take a deeper look into proto buff serialization (https://developers.google.com/protocol-buffers/docs/encoding). I have no idea how it works, but maybe the message is compressed, so repeated []bytes maybe be discarded.

Is there a way that we can emit error or success manually on Future dart?

Something like SettableFuture/ListenableFuture java where we can control what to emit to the listener.
What I want to have is :
For example, I have a socket connection active.
I send(request) a message through socket in some function
The request also has its response, but it comes through onData(d) callback some where else not in this request funtion
I store the future in a key-value array after send
After the response on onData(d) I will get the future from the array and make it emit success or error appropriately
Normally you can make an asynchronous function either return a value (success) or throw an exception (either by throwing from a async function or by manually returning a Future.error).
If you have some existing Future that you don't control, you can't force it to succeed or to fail. You instead could make callers wait on a Future that you do control, and you could make your Future depend on the external one.
Completer can simplify some of that for you.

How to Use ServeMux with ServerConn?

Im creating a Networking API and want people to be able to route requests to specific endpoints using a ServeMux. Instead of using a Server instance, I need to use my own low level ServerConn. This is because I am receiving both incoming HTTP requests and plain text data from the same port.
The problem, however, is that if I want to forward a request using my ServeMux, I would use it's ServeHTTP method. For this, I need to provide a ResponseWriter, which I don't know how to create an instance of since it is an interface, not a struct. Should a I create my own ResponseWriter struct? Is there one given by the Golang Standard Library? Or is there an alternate solution to this altogether?
I would avoid doing this altogether if at all possible. Mixing protocols on the same connection is bound to lead to hard-to-trace bugs, and unexpected behavior. If you really want to do it, and have all the http/1.1 mechanisms work correctly, leave as much as possible to the http package.
Since ResponseWriter is an interface, you would implement your own type to satisfy it. Look at the unexported response type in the http package for a full example. There's a lot to get right, and using it in combination with a ServerConn (which is documented as "do no use") is probably not a good idea.
The place to do this at a lower level would be in Accept inside the Server's net.Listener. Since you're going to have to parse the start of every request twice, you would need a net.Conn that can be "rewound" partly.
Make yourself a net.Listener that checks the start of the stream on a new connection, and if it looks like an http request, return a net.Conn that replays the first chunk you read off the wire on its first Reads. Something like:
type replayConn struct {
net.Conn
buf []byte
pos int
}
func (c *replayConn) Read(b []byte) (int, error) {
if c.pos < len(c.buf) {
n := copy(b, c.buf[c.pos:])
c.pos += n
return n, nil
}
return c.Conn.Read(b)
}
If the connection isn't http, then send the connection off to your other type of handler, and continue blocking on Accept.

Lifecycle of servlet filter doFilter method

I'm trying to set a header in the response object after I call
chain.doFilter()
However, the header does not get set. Does control ever come back to the doFilter() method after a call to chain.doFilter()?
However, the header does not get set.
That can happen if the response is already committed (read: when the first part of the response, including all headers, are already been sent to the client; this is a point of no return). A bit sane servletcontainer would throw an IllegalStateException on any attempt to set a header on an already committed response. This should be visible in the server logs. Have you read them?
Does control ever come back to the doFilter() method after a call to chain.doFilter()?
You could easily check it yourself by placing a breakpoint or a sysout/logger line. But yes, surely the control comes back the usual Java way and the remaining lines will be executed, provided that there's no uncaught exception coming from the doFilter() call.
Coming back to your concrete functional requirement, you'd need to rewrite your code in such way that the header is been set before the response is ever committed. As the concrete functional requirement is not elaborated in any way, it's not possible to give some hints or kickoff examples in this answer. The most straightforward way would be to just set the header before calling doFilter().
Request filters can:
perform security checks
reformat request headers or bodies
audit or log requests
Response filters can:
compress the response stream
append or alter the response stream
create a different response altogether

Resources