0
votes

I am using apostrophe with apostrophe-headless. I have an apostrophe-pieces module called bundles, which I would like to filter based on a custom field. The documentation and it says that I need to define an apostrophe-pieces-pages module in order to enable that.

This is my configuration:

  'bundles': {
    extend: 'apostrophe-pieces',
    name: 'bundles',
    restApi: {
      maxPerPage: 10,
    }
  },

  'bundles-pages': {
    extend: 'apostrophe-pieces-pages',
    piecesFilters: [
      {
        name: 'name'
      },
      {
        name: 'slug'
      }
    ]
  },

If I do full text search:

/api/v1/bundles?page=1&search=text 

it works as expected, but if I try to filter on the slug:

/api/v1/bundles?page=1&slug=slug_value 

it returns all bundles instead of the matching one.

2

2 Answers

1
votes

apostrophe-pieces-pages are not required to make cursor filter methods available to the API and other code. I think that confusion comes from the fact that the documentation focuses on apostrophe-pieces-pages because rendering full pages directly is the use case the main series of Apostrophe tutorials focuses on.

With help from you, we have updated apostrophe-headless to support an option to specify filters that should be marked "safe" for the public API in the same way that apostrophe-pieces-pages does it:

'my-module': {
  restApi: {
    // We're assuming here that you have added fields
    // called 'color' and 'brand' in your schema
    safeFilters: [ 'slug', 'color', 'brand' ]
  }
}

However, for anyone keen to query on the slug property in particular, keep in mind that if you're making API calls you are probably better off fetching things by their _id, using the documented REST pattern:

/api/v1/bundles/IDGOESHERE

Slugs, unlike the _id, are subject to occasional change. If you know the _id and you're not creating a user-facing "friendly URL" then you should use the _id.

0
votes

I was running into the same problem and found the solution was to add a custom filter as documented here: https://apostrophecms.org/docs/tutorials/intermediate/cursors.html#custom-filters

The only change I made to the sample code shown in that link is on the line starting with self.and({... The problem is that when no documents match the specific slug, then the and still returns the initial cursor which contains all the documents but really you need it to return nothing. So, instead of :

self.and({ marketId: market._id });

I did this (bit hacky, but you get the idea):

self.and({ marketId: market === undefined ? 9999999999 : market._id });