statamic / ideas

💡Discussions on ideas and feature requests for Statamic
https://statamic.dev
30 stars 1 forks source link

Add include_children to API #999

Open jackmcdade opened 1 year ago

jackmcdade commented 1 year ago

Right now you can query for a tree, or an entry, but no way I can see to just get an entry and its children. We should support this.

Smef commented 1 year ago

To add some more details here, when you query a tree by default, you get pages with the children included. Example: /api/collections/documentation/tree

{
  "data": [
    {
      "page": {...},
      "depth": 1,
      "children": [
        {...},
        {...},
        {...}
      ]
    }
  ]
}

If you add a filter to this to find a single top-level element, you can get the same thing, but the children array is empty Example: /api/collections/documentation/tree?filter[id]=e5d47e42-b82c-45c7-8138-5ba3516a6edf

{
  "data": [
    {
      "page": {...},
      "depth": 1,
      "children": []
    }
  ]
}

I've found one work around for this is to give the collection calculated route attributes so that all the children have URLs which build on the parent's route. This allows querying based on the starting text of the route, and the children are all included in the results {{ depth == 1 ?= 'docs' }}/{{ parent_uri }}/{{ slug }}

In this example, the parent's route is /docs/my-product and all of the children's route's also start with the same /docs/my-product and then build from there, such as /docs/my-product/getting-started. Filtering by url results in the children all being included in the query.

Example Query /api/collections/documentation/tree?filter[url:starts_with]=/docs/my-product

{
  "data": [
    {
      "page": {...},
      "depth": 1,
      "children": [
        {...},
        {...},
        {...}
      ]
    }
  ]
}

In our use case we are using Statamic as a headless CMS, so the routes don't really mean anything like the would if it was full-stack. Using the route attribute of the collection seems to give us a solution to the problem, but it feels a bit hack-ey and doesn't seem like this should be the right way to do this.

Directly getting the children from the API definitely seems like the right way for this to work.