nazirov91 / ra-strapi-rest

React Admin data provider for Strapi.js
125 stars 40 forks source link

Data provider for strapi 3.0.0 beta version #9

Closed yogesh-dalvi closed 4 years ago

yogesh-dalvi commented 4 years ago

How to use this data provider for strapi's beta version as using this data provider requires us to add a Content-Range header in the strapi's controller's plugin which is not provided in the beta version. In beta version of strapi the controller's and service's are empty for any plugin we install externally.

maddog986 commented 4 years ago

Im also here to see if anyone has a solution for this...

Rendiere commented 4 years ago

+1 - controller is empty for content types on the API, so it's unclear how to implement the Content-Range header fix from scratch.

nazirov91 commented 4 years ago

The solution is simple: just extend the find method of each controller.

Say you have a Strapi API /post and corresponding Post.js controller file. But the file is empty

// api/post/controllers/Post.js
'use strict'

module.exports = {};

According to the Strapi Documentation, when you create a new Content or model, Strapi builds a generic controller for your models by default and allows you to override and extend it in the generated file.

So to make the React-Admin work, we have to extend the find method of the post controller.

// api/post/controllers/Post.js

'use strict';
const { sanitizeEntity } = require('strapi-utils');

module.exports = {
  async find(ctx) {
    let entities;
    ctx.set('Content-Range', await strapi.services.post.count()); // <--- Add this guy
    if (ctx.query._q) {
      entities = await strapi.services.post.search(ctx.query);
    } else {
      entities = await strapi.services.post.find(ctx.query);
    }

    return entities.map(entity =>
      sanitizeEntity(entity, { model: strapi.models.post })
    );
  },
};

Note that my model name is called post here. Replace it with whatever content you are dealing with.

The content-range header is required only for the find method

Please let me know if this does not work. Thanks!

yogesh-dalvi commented 4 years ago

The solution is simple: just extend the find method of each controller.

Say you have a Strapi API /post and corresponding Post.js controller file. But the file is empty

// api/post/controllers/Post.js
'use strict'

module.exports = {};

According to the Strapi Documentation, when you create a new Content or model, Strapi builds a generic controller for your models by default and allows you to override and extend it in the generated file.

So to make the React-Admin work, we have to extend the find method of the post controller.

// api/post/controllers/Post.js

'use strict';
const { sanitizeEntity } = require('strapi-utils');

module.exports = {
  async find(ctx) {
    let entities;
    ctx.set('Content-Range', await strapi.services.post.count()); // <--- Add this guy
    if (ctx.query._q) {
      entities = await strapi.services.post.search(ctx.query);
    } else {
      entities = await strapi.services.post.find(ctx.query);
    }

    return entities.map(entity =>
      sanitizeEntity(entity, { model: strapi.models.post })
    );
  },
};

Note that my model name is called post here. Replace it with whatever content you are dealing with.

The content-range header is required only for the find method

Please let me know if this does not work. Thanks!

Hey @nazirov91 thanks a lot, it helped!

Rendiere commented 4 years ago

Thank you @yogesh-dalvi , that makes a lot more sense now.

However, I'm even after adding that find method in the controller for the Model with the line that sets the "Content Range" on ctx, my api returns a 200 response, with the correct data but without the content-rage header. In fact, the response of my API contains an empty Header.

I'm probably missing something stupid, so any help would be appreciated.

Rendiere commented 4 years ago

Nevermind, found my error -> I was setting the content range within the if statement >_<.