Luis Nuño
Luis Nuño

Reputation: 1

Can I build a DslPart using an existing one as part of the new one?

I'm writing some Pact Tests of an endpoint that returns an specific product when the id is passed as path param or an array of all products when no id is specified:

{baseUrl}/products/1

{
    "id": 1,
    "name": "product1",
    "type": "example",
    "attributes": [
        {
            "attrib1": "text1",
            "attrib2": "text2",
            "attrib3": "text3",
        },
        {
            "attrib1": "string1",
            "attrib2": "string2",
            "attrib3": "string2",
        },
    ]
}

{baseUrl}/products

{
    "products": [
        {
            "id": 1,
            "name": "product1",
            "type": "example",
            "attributes": [
                {
                    "attrib1": "text1",
                    "attrib2": "text2",
                    "attrib3": "text3"
                },
                {
                    "attrib1": "string1",
                    "attrib2": "string2",
                    "attrib3": "string3"
                }
            ]
        },
        {
            "id": 2,
            "name": "product2",
            "type": "example",
            "attributes": [
                {
                    "attrib1": "text1",
                    "attrib2": "text2",
                    "attrib3": "text3"
                },
                {
                    "attrib1": "string1",
                    "attrib2": "string2",
                    "attrib3": "string3"
                },
                {
                    "attrib1": "abc1",
                    "attrib2": "abc2",
                    "attrib3": "abc3"
                }
            ]
        },
        {
            "id": 3,
            "name": "product3",
            "type": "example",
            "attributes": [
                {
                    "attrib1": "text1",
                    "attrib2": "text2",
                    "attrib3": "text3"
                }
            ]
        }
    ]
}

I'm building the JSON body of an individual product by using a Lambda DSL:

DslPart product = newJsonBody((body) -> {
    body.numberType("id", 1);
    body.stringType("name", "product1");
    body.stringType("type", "example");
    body.array("attributes", (attributes) -> {
        attributes.object((attrib) -> {
            attrib.stringType("attrib1", "text1");
            attrib.stringType("attrib2", "text2");
            attrib.stringType("attrib3", "text3");
        });
    });
}).build();

So far so good, but now want to build the response body of the list of products and I would like to reuse the DslPart product that I already have.

Something like this:

DslPart productList = newJsonBody((body) -> {
    body.array("products", (products) -> {
        products.object(product);        // This is not possible, a LambdaDslObject is required
    });
}).build();

Until now the only way I have found is to rewriting the entire product inside the products array

Upvotes: 0

Views: 138

Answers (1)

Gaël J
Gaël J

Reputation: 15285

There might be an easier way thanks to Pact helper methods but otherwise this is plain Java and you can extract the lambdas as values.

Consumer<LambdaDslObject> productConsumer = (obj) -> {
    obj.numberType("id", 1)
    obj.stringType("name", "product1")
    obj.stringType("type", "example")
    ...
}

// In Java we are forced to do so because even though LambdaDslJsonBody is a subtype of LambdaDslObject, Consumer<LambdaDslObject> is not a subtype of Consumer<LambdaDslJsonBody>
Consumer<LambdaDslJsonBody> productConsumerVariant = (body) -> {
    productConsumer.accept(body)
}

DslPart product = LambdaDsl.newJsonBody(productConsumerVariant).build()

DslPart productList = LambdaDsl.newJsonBody((body) -> {
    body.array("products", (products) -> {
      products.`object`(productConsumer)
    })
  }).build

(There may be some syntax typos in the lambdas declaration, feel free to correct, I haven't write Java for some time!)

Upvotes: 0

Related Questions