lura icon indicating copy to clipboard operation
lura copied to clipboard

How aggregate collection element for filling data about linked resource?

Open SmotrovaLilit opened this issue 4 years ago • 1 comments

I prepared an example. Suppose I have users backend service with those API endpoints:

  • Get concrete user GET /users/{user_id} that responses with:
{
"id": "34",
"name": "Bob"
}
  • Get users with filter by id GET /users?ids=34,35 that responses with:
{
  "data": [
    {
      "id": "34",
      "name": "Bob"
    },
    {
      "id": "35",
      "name": "Alice"
    }
  ]
}

And I have apples backend service with this endpoint

  • Get apples GET https://backend1/apples that responses with:
{
  "data": [
    {
      "id": "1",
      "sort": "gold",
      "owner_id": "34"
    },
    {
      "id": "2",
      "sort": "silver",
      "owner_id": "35"
    }
  ]
}

Which endpoint configuration I should use to get that endpoint response?:

{
  "data": [
    {
      "id": "1",
      "sort": "gold",
      "owner": {
        "id": "34",
        "name": "Bob"
      }
    },
    {
      "id": "2",
      "sort": "gold",
      "owner": {
        "id": "35",
        "name": "Alice"
      }
    }
  ]
}

==============================================================================

I know how to aggregate backend responses when I do not use collections, using krakend proxy https://www.krakend.io/docs/endpoints/sequential-proxy/.

An example is here https://gist.github.com/SmotrovaLilit/17202ea12a9f58d347676f9a2f7f31f5

But I don't know how to do it for collections.

SmotrovaLilit avatar Dec 11 '20 20:12 SmotrovaLilit

Somehow I am looking for a solution like this to replace the data in lists with the extended one from other endpoints. and I figured maybe having a signature like this works.

 {
  "endpoint": "/product/{productId}/reviews",
  "backend": [
    {
      "host": ["http://reviews-service:8080"],
      "url_pattern": "/v1/reviews?product_id={productId}"
    },
    {
      "host": ["http://customers-service:8080"],
      "url_pattern": "/v1/customers?id={data.*.customer_id,data.*.id,customer,true}"
    },
  ],
  "extra_config": {
    "github.com/devopsfaith/krakend/proxy": {
      "aggregator": "true"
    }
  }
 }

so if we assume the response of the first endpoint (which is the main endpoint) is:

{
  "data": [
    {
      "customer_id" : 456,
      "review" : "it's a good product."
    },
    {
      "customer_id" : 567,
      "review" : "it's an awesome product."
    }
  ],
  ...
}

and the response of the second endpoint (or other endpoints as well) is this:

{
  "data": [
    {
      "id" : 456,
      "name" : "john",
      "email" : "[email protected]"
    },
    {
      "id" : 567,
      "name" : "aliss",
      "email" : "[email protected]"
    }
  ],
  ...
}

the final response will be:

{
  "data": [
    {
      "customer": {
        "id": 456,
        "name": "john",
        "email": "[email protected]"
      },
      "review": "it's a good product."
    },
    {
      "customer": {
        "id": 567,
        "name": "aliss",
        "email": "[email protected]"
      },
      "review": "it's an awesome product."
    }
  ],
  ...
}

and about {data.*.customer_id,data.*.customer_id,customer,true} this can be 2, 3, or 4 parts, the first part is the attribute in the main response and the second part is its peer attribute in the second response with the same value. the third part is optional, addresses the new attribute name if it wants to be under a new name, and the fourth part is optional as well indicates whether the first attribute should be removed from the response or not. so when the router gets the request, this section will be replaced by the comma separated list of that attribute, in our example it will be : /v1/customers?id=465,567

I want to implement this feature, I think the scenario is ok and I'm also open to new ideas.

p3ym4n avatar Dec 23 '20 23:12 p3ym4n

with requirements like this, you can't get it done with just configuration, but you can use a response modifier plugin at the endpoint level, encapsulating all the logic required by your use case

kpacha avatar Nov 24 '22 19:11 kpacha

This issue was marked as resolved a long time ago and now has been automatically locked as there has not been any recent activity after it. You can still open a new issue and reference this link.

github-actions[bot] avatar Feb 23 '23 00:02 github-actions[bot]