Stefan
Stefan

Reputation: 749

JSON Serialization of pojos with child objects

Let's say I have a restful webservice with the following interfaces:

GET /some/parent

This will return something like

[
    {
        urn: "/some/parent/1",
        name: "parent1",
        children: [ "/some/child1", "/some/child2" ]
    },
    {
        urn: "/some/parent/2",
        name: "parent2",
        children: [ "/some/child3", "/some/child4" ]
    }
]

and, i've got

GET /some/parent/{id}

that return something like this:

{
    urn: /some/parent/1,
    name: parent1,
    children: [
        {
            urn: "/some/child1",
            name: "child1"
        },
        {
            urn: "/some/child2",
            name: "child2"
        }
    ]
}

So, when requesting a list of parents, the json representations for every parent will be list with the child urns. When requesting a specific parent resource the json representation will contain a list of child json representations.

With jersey the common way would be to define two simple java pojos and a simple Resource:

public class Parent {
    private String id;
    private String name;
    private List<String> childIds;
    ...
    @JsonIgnore
    public String getId()...
    @JsonProperty
    public String getUrn()...
}

public class Child {
    private String id:
    private String name;
    ...
    @JsonIgnore
    public String getId()...
    @JsonProperty
    public String getUrn()...
}

@Path("/some/parent")
@Produces(MediaType.APPLICATION_JSON)
public class ParentResource() {
    @GET
    public List<Parent> findAll() {
        List<Parent> result = // some database query call
        return result;
    }

    @GET
    @Path("{id}")
    public Parent find(@PathParam("id") String id) {
        Parent parent = // some database call
        return parent;
    }
}

How can I inject the child urns/objects in the above scenarios? Are there any best practices? How do you solve this?

Thanks.

Upvotes: 2

Views: 3933

Answers (2)

Stefan
Stefan

Reputation: 749

In this case I would rather make an extended Parent class like this:

public class ParentExtended extends Parent {
    private List<Child> childrenObjects;

    public ParentExtended(Parent parent) {
        this.id = parent.getId();
        ...
    }

    @JsonProperty("children")
    public List<Child> getChildrenObjects() { ... }

    @Override
    @JsonIgnore
    public List<String> getChildren() { ... }
}


@Path("/some/parent")
@Produces(MediaType.APPLICATION_JSON)
public class ParentResource() {
    @GET
    public List<Parent> findAll() {
        List<Parent> result = // some database query call
        return result;
    }

    @GET
    @Path("{id}")
    public ParentExtended find(@PathParam("id") String id) {
        Parent parent = // some database call
        ParentExtended parentEx = new ParentExtended(parent);

        for (String childId : parent.getChildren()) {
            parentEx.getChildrenObjects().add(// fetch the child object);
        }
        return parentEx;
    }
}

It is not a very nice way. I am open to other alternatives...

Upvotes: 1

Rick Mangi
Rick Mangi

Reputation: 3769

You don't store the child ids in the parent object, you store a list of the children as objects...

public class Parent {
    private String id;
    private String name;
    private List<Child> children;
    ...
    @JsonIgnore
    public String getId()...
    @JsonProperty
    public String getUrn()...
}

Upvotes: 0

Related Questions