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.

2.X.X deprecates UUIDParam, SizeParam, LocalDateParam, InstantParam, DurationParam, DateTimeParam, BooleanParam and does not give clear alternatives

See original GitHub issue

I’m trying to upgrade Dropwizard from 1.3.23 to 2.0.10 and am running into some issues around the use of parameters. Specifically, I see that this commit deprecated a number of *Param classes.

Some of these, like IntParam are straightfoward. Using OptionalInt as a replacement makes sense. However, taking non-primitive parameters as an example, Optional<UUID> is NOT a sufficient replacement for UUIDParam. Using it results in me getting a 404 when using a non-UUID as input (where I previously got 400 using UUIDParam).

Additionally, and maybe this is a separate issue, I found the compatibility-preserving use of UUIDParam is strange. When diving into the source code, I found this resource method[1]:

        @GET
        @Path("/uuid")
        public String getUUID(@QueryParam("uuid") Optional<UUIDParam> uuid) {
            return uuid.orElse(new UUIDParam("d5672fa8-326b-40f6-bf71-d9dacf44bcdc")).get().toString();
        }

This construct seems an extremely clunky way to manage this. In 1.3.X, I could write code like this instead:

        @GET
        @Path("/uuid")
        public String getUUID(@Nullable @QueryParam("uuid") UUIDParam uuid) {
            if (uuid != null) {
                return uuid.get()
            } else {
                return "d5672fa8-326b-40f6-bf71-d9dacf44bcdc"
            }
        }

You can see in the above that there is a lot of unnecessary conversion going on (we construct a UUID via UUIDParam and validate it, even though we just want to return a String). I use Kotlin primarily, my preferred example above would be even simpler:

uuid.get()?.toString ?: "d5672fa8-326b-40f6-bf71-d9dacf44bcdc"

What I’d prefer overall is something that worked like this:

        @GET
        @Path("/uuid")
        public String getUUID(@Nullable @QueryParam("uuid") Optional<UUID> uuid) {
            return uuid.map { it.toString() }.orElse("d5672fa8-326b-40f6-bf71-d9dacf44bcdc")
        }

More than anything, really, I just want some guidance for the right way to handle various param types, especially in light of the deprecation. The documentation is light on this (I found the MR saying AbstractParam and child classes will be removed, but nothing saying why, and no code showing what would replace the more complicated use-cases like UUIDParam above). I would love to see this improved. Until then, I’m hesitant to upgrade to 2.X.X. Param handling is still confusing in 1.X.X, but at least I won’t have to worry about behavior changes.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
sleberknightcommented, Jul 16, 2020

We also have experienced similar problems but with regular old long parameters, e.g. OptionalLong and Optional<Long> which behave completely differently. (The same goes for OptionalInt and Optional<Integer> etc). Here is a sample endpoint using optionals:

    @GET
    @Path("/optionalsTest/{param1}/{param2}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response optionalsTest(@PathParam("param1") OptionalLong param1,
                                  @PathParam("param2") Optional<Long> param2) {

        var entity = Map.of(
                "param1", param1.getAsLong(),
                "param2", param2.get()
        );

        return Response.ok(entity).build();
    }

Observed behavior:

If you do GET /optionalsTest/42/84, you get a 200 response with the expected response entity.

If you do GET /optionalsTest/abcd/84, you get a 500 response.

If you do GET /optionalsTest/42/abcd, you get a 404 response.

So, when using OptionalLong and supplying a non-numeric value, you get a 500 which is very confusing behavior. It should be a 400 as LongParam would do.

But, when using Optional<Long> and supplying a non-numeric value, you get a 404 which is maybe even more confusing than getting a 400 or 500.

Using LongParam always gives a 400 response and gives a nice error message as well. For this sample endpoint:

    @GET
    @Path("longParamTest/{param1}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response optionalsTest(@PathParam("param1") LongParam param1) {

        var entity = Map.of("param1", param1.get());

        return Response.ok(entity).build();
    }

If you do GET /longParamTest/abcd you get a 400 response with the following body:

{
    code: 400,
    message: "path param param1 is not a number."
}

So while I have no problem using OptionalLong or Optional<Long> etc. (other than both IntelliJ and Sonar complaining about using optionals for method arguments), the completely different behavior (i.e. the 500 for OptionalLong and 400 for Optional<Long) is confusing and not as clear as the behavior LongParam exhibits (as well as all the other XxxParam classes).

0reactions
github-actions[bot]commented, Apr 21, 2021

This issue is stale because it has been open 90 days with no activity. Remove the “stale” label or comment or this will be closed in 14 days.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Index (Dropwizard Project 2.0.3 API) - javadoc.io
Utility class to configure logging before the dropwizard yml configuration has been read, parsed, and the provided logging strategy has been applied.
Read more >
Dropwizard Documentation - Read the Docs
Running your application as a simple process eliminates a number of unsavory aspects of Java in production (no PermGen issues, no application server ......
Read more >
Jenkins CascadeChoiceParameter causes ...
The following seems to work fine for me. Try updating the Plugin maybe. def CATEGORY = "" properties([ parameters([ [ $class: ...
Read more >
Pipeline Syntax - Jenkins
There is currently an open issue which limits the maximum size of the code within the pipeline{} block. This limitation does not apply...
Read more >
parameters - Jenkins Job DSL Plugin
Allows to parameterize the job. Examples. job('example') { parameters { booleanParam('FLAG', true) choiceParam ...
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