question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Additional Request Completion Methods that support Futures

See original GitHub issue

Describe the feature Adding more request completion methods (eg: Context#result(...) that support futures as you don’t always need to specify a response body for a request, sometimes a Status Code of 401 Unauthorized is fine.

Additional context

Some of the methods that I am thinking of are as follows but please note that all the methods outlined assume that the generic type variable from the CompletableFuture is Nullable.

Context#status(int)
Context#status(CompletableFuture<Integer>)

Context#json(Any)
Context#json(CompletableFuture<Any>) 

Context#result(String)
Context#result(CompleteableFuture<String>)
Context#result(byte[])
Context#result(CompleteableFuture<Byte[]>)
Context#(InputStream)
Context#result(CompleteableFuture<InputStream>)

One useful usecase would be if you are querying for a document from a database and then going to return that response (if any) as json as it makes for neater code:

Context#json(CompletableFuture.supplyAsync(() -> {
  final Document document = this.mongo.find(Filters.eq("_id", ctx.pathParam("id", ObjectId.class).get())).first();

  if (document == null) {
    ctx.status(HttpStatus.NO_CONTENT_204);
    return null; // Hello Javalin I don't have any Object for you to convert to Json using JavalinJson do not set the ContentType.JSON do not add a Response Body please.
  }

  Context#status(HttpStatus.OK_200);
  return document; // Hello Javalin please convert this Object to Json using JavalinJson
}));

One thing to note about this example is serializing a Bson Document to json isn’t going to give your returned response as a valid response you would want. You actually have to tell Bson to write as a json string first, for example:

ctx -> {
    ctx.status(HttpStatus.OK);
    ctx.contentType(ContentType.JSON);
    ctx.result(Document#toJson(JsonWriterSettings, Encoder));
}

This leads me onto the next thing; having a Context#json(String jsonString) method that sets the Content Type to JSON and then sets the body to the jsonString value would also be useful. Sometimes I already have the jsonString due to Bson so I can’t use Context#json(String) because that then serializes my jsonString AGAIN, causing issues. Also in case I haven’t mentioned this, Context#json(String) does not support a null argument so I have to hack around all of this with:

Context.result(CompleteableFuture.supplyAsync(() -> {
  final Document document = this.mongo.find(Filters.eq("_id", ctx.pathParam("id", ObjectId.class).get())).first();

  if (document == null) {
    ctx.status(HttpStatus.NO_CONTENT_204);
    return null;
  }
  
  ctx.statusCode(HttpStatus.OK_200);
  ctx.contentType(ContentType.JSON); // Notice how we specify this all of the time?
  
  return this.gson.toJson(document); // Again, for Mongo you'd do Document#toJson(JsonWriterSettings, Encoder) instead of gson.
}));

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:25 (25 by maintainers)

github_iconTop GitHub Comments

1reaction
tipsycommented, Jun 10, 2021

It’s now:

fun json(future: CompletableFuture<*>) = result(future.thenApply {
    if (it != null) JavalinJson.toJson(it).also { contentType("application/json") } else ""
})

And these assertions pass:

assertThat(contentResponse.status).isEqualTo(200)
assertThat(contentResponse.body).isEqualTo("""{"value1":"FirstValue","value2":"SecondValue"}""")
assertThat(contentResponse.headers.getFirst(Header.CONTENT_TYPE)).isEqualTo("application/json")

assertThat(noContentResponse.status).isEqualTo(204)
assertThat(noContentResponse.body).isEqualTo(null)
assertThat(noContentResponse.headers.getFirst(Header.CONTENT_TYPE)).isEqualTo("text/plain")
Read more comments on GitHub >

github_iconTop Results From Across the Web

Future (Java Platform SE 7 ) - Oracle Help Center
Additional methods are provided to determine if the task completed normally or was cancelled. Once a computation has completed, the computation cannot be ......
Read more >
concurrent.futures — Launching parallel tasks — Python 3.11 ...
If cancel_futures is True , this method will cancel all pending futures that the executor has not started running. Any futures that are...
Read more >
Guide To CompletableFuture - Baeldung
This method of creating and completing a CompletableFuture can be used with any concurrency mechanism or API, including raw threads. Notice that ...
Read more >
CME Group Options on Futures
CME Group's vast and liquid family of option contracts on futures can help you diversify your portfolio while helping to mitigate your downside...
Read more >
Asynchronous programming: futures, async, await - Dart
When you call an asynchronous function, it returns an uncompleted future. That future is waiting for the function's asynchronous operation to finish or...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found