Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typed client: force sending null value #2251

Closed
jmini opened this issue Dec 20, 2024 · 11 comments
Closed

Typed client: force sending null value #2251

jmini opened this issue Dec 20, 2024 · 11 comments

Comments

@jmini
Copy link
Contributor

jmini commented Dec 20, 2024

It seem that the gitlab graphql server has a very specific way of treating null.

I looked at the query created by the js graphQL client when an action (removing the due-date of a workItem) is created in the UI. It's send:

{
    "input": {
        "id": "gid://gitlab/WorkItem/18672",
        "rolledupDatesWidget": {
            "dueDateIsFixed": true,
            "startDateIsFixed": true,
            "dueDateFixed": null,
            "startDateFixed": null
        }
    }
}

I was able to reproduce it in graphiQL https://gitlab.com/-/graphql-explorer

Screenshot 2024-12-20 at 09 39 14

Corresponding java code:

WorkItemUpdateInput request = new WorkItemUpdateInput()
        .setId(workItem.getId())
        .setRolledupDatesWidget(new WorkItemWidgetRolledupDatesInput()
                .setDueDateFixed(null)
                .setDueDateIsFixed(true)
                .setStartDateFixed(null)
                .setStartDateIsFixed(true) //
        ) //
;
WorkItemUpdatePayload updateResponse = api.workItemUpdate(request);

Library is here: https://github.com/unblu/gitlab-workitem-graphql-client

But this is turned by the typed-client to this request:

{"arg0":{"id":"gid://gitlab/WorkItem/18672","rolledupDatesWidget":{"startDateIsFixed":true,"dueDateIsFixed":true}}}

The null values are not sent, and it seem that this is interpreted differently by the server.

If change graphiQL to:

{
    "input": {
        "id": "gid://gitlab/WorkItem/18672",
        "rolledupDatesWidget": {
            "dueDateIsFixed": true,
            "startDateIsFixed": true
        }
    }
}

As with the java typed client, no change is performed by the server.


Is it a way to force the GraphQL client to set the null values?

@jmini
Copy link
Contributor Author

jmini commented Dec 20, 2024

I somehow need to set something like:

JsonbConfig config = new JsonbConfig()
  .withNullValues(true)

@jmini
Copy link
Contributor Author

jmini commented Dec 20, 2024

I was exactly looking at those, but they are server-side features.
So I am not sure (yet) how to do this at client side 🤔

@jmartisk
Copy link
Member

Ah, sorry! I guess my brain was turned off.

I think we don't have explicit control over this on the client, but I vaguely remember we had a debate that when you use a record instead of a class, then its null fields will be included. Maybe you could try that, but otherwise, this is something that we would have to implement (maybe a configuration property)

@jmini
Copy link
Contributor Author

jmini commented Dec 20, 2024

I have change the class WorkItemWidgetRolledupDatesInput to a record:

package graphql.gitlab.model;

import org.eclipse.microprofile.graphql.Name;

@Name("WorkItemWidgetRolledupDatesInput")
public record WorkItemWidgetRolledupDatesInput(Date startDateFixed, Boolean startDateIsFixed, Date dueDateFixed, Boolean dueDateIsFixed) {
}

And the query to:

WorkItemUpdateInput request = new WorkItemUpdateInput()
        .setId(workItem.getId())
        .setRolledupDatesWidget(
                new WorkItemWidgetRolledupDatesInput(null, true, null, true) //
        );
WorkItemUpdatePayload updateResponse = api.workItemUpdate(request);

And it does not seems to have any impact (which I think makes sense).


Side not on the usage of records:

The mutation query we formulate now with classes (using a builder pattern and chain-able setters) is quite convenient.

  • It is close to the json that can be written in a tool like graphiQL
  • Now we we have divided our code in multiple methods making some contributions to the builder

So I don't think I would like to use records for my graphQL queries.

@jmini
Copy link
Contributor Author

jmini commented Dec 20, 2024

I think I found it:

private JsonObject objectValue(Object object, Stream<FieldInfo> fields) {
JsonObjectBuilder builder = jsonObjectFactory.createObjectBuilder();
fields.forEach(field -> {
if (field.isIncludeNull() || field.get(object) != null) {
builder.add(field.getName(), value(field.get(object)));
}
});
return builder.build();

And:

if (jsonbPropertyAnnotation != null) {
includeIfNull = jsonbPropertyAnnotation.nillable();
} else {
includeIfNull = false;
}

So the solution is:

public class WorkItemWidgetRolledupDatesInput {

    /**
     * Fixed start date for the work item.
     */
    @JsonbProperty(value = "startDateFixed", nillable = true)
    private Date startDateFixed;
    /**
     * When start_date_fixed is not provided it defaults to `false`.
     */
    private Boolean startDateIsFixed;
    /**
     * Fixed due date for the work item.
     */
    @JsonbProperty(value = "dueDateFixed", nillable = true)
    private Date dueDateFixed;
    /**
     * When due_date_fixed is not provided it defaults to `false`.
     */
    private Boolean dueDateIsFixed;
    
    // ...

@jmini jmini closed this as completed Dec 20, 2024
@jmini
Copy link
Contributor Author

jmini commented Dec 20, 2024

@jmartisk thank you very much for your help

jmini added a commit to unblu/gitlab-workitem-graphql-client that referenced this issue Dec 20, 2024
@jmartisk
Copy link
Member

Ah, good catch, I'd forgotten about that! Ok, glad that it's resolved.

@jmini
Copy link
Contributor Author

jmini commented Dec 20, 2024

I just saw that the nillable = true attribute is replaced by @JsonbNillable

See: https://jakarta.ee/specifications/jsonb/3.0/apidocs/jakarta.json.bind/jakarta/json/bind/annotation/jsonbproperty#nillable()

So I guess a follow up issue/PR to fix FieldInfo is needed.

@jmartisk
Copy link
Member

Feel free to send a PR :)

@jmini
Copy link
Contributor Author

jmini commented Dec 30, 2024

See #2253 for support of @JsonbNillable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants