Is there a way to get a structure of a Strapi CMS Content Type?
Asked Answered
A

2

6

A content-type "Product" having the following fields:

  • string title
  • int qty
  • string description
  • double price

Is there an API endpoint to retrieve the structure or schema of the "Product" content-type as opposed to getting the values?

For example: On endpoint localhost:1337/products, and response can be like:

[
  {
    field: "title",
    type: "string",
    other: "col-xs-12, col-5"
  },
  {
    field: "qty",
    type: "int"
  }, 
  {
    field: "description",
    type: "string"
  },
  {
    field: "price",
    type: "double"
  }
]

where the structure of the schema or the table is sent instead of the actual values?

If not in Strapi CMS, is this possible on other headless CMS such as Hasura and Sanity?

Addend answered 12/2, 2021 at 22:51 Comment(0)
P
3

You need to use Models, from the link:
Link is dead -> New link

Models are a representation of the database's structure. They are split into two separate files. A JavaScript file that contains the model options (e.g: lifecycle hooks), and a JSON file that represents the data structure stored in the database.

This is exactly what you are after.
The way I GET this info is by adding a custom endpoint - check my answers here for how to do this - https://mcmap.net/q/1780458/-how-to-include-a-field-in-api-without-adding-the-key-val-in-database & https://mcmap.net/q/1780459/-how-to-add-custom-route-for-user.

For handlers you can do something like:

async getProductModel(ctx) {
  return strapi.models['product'].allAttributes;
}

I needed the solution for all Content Types so I made a plugin with /modelStructure/* endpoints where you can supply the model name and then pass to a handler:

//more generic wrapper
async getModel(ctx) {
  const { model } = ctx.params;
  let data = strapi.models[model].allAttributes;
  return data;
},
async getProductModel(ctx) {
  ctx.params['model'] = "product"
  return  this.getModel(ctx)
},

//define all endpoints you need, like maybe a Page content type
async getPageModel(ctx) {
  ctx.params['model'] = "page"
  return  this.getModel(ctx)
},

//finally I ended up writing a `allModels` handler
async getAllModels(ctx) {
  Object.keys(strapi.models).forEach(key => {
       //iterate through all models
       //possibly filter some models
       //iterate through all fields
       Object.keys(strapi.models[key].allAttributes).forEach(fieldKey => {
           //build the response - iterate through models and all their fields
       }
   }
   //return your desired custom response
} 

Comments & questions welcome

Phoenician answered 14/2, 2021 at 16:51 Comment(0)
A
1

This answer pointed me in the right direction, but strapi.models was undefined for me on strapi 4.4.3.

What worked for me was a controller like so:

async getFields(ctx) {
    const model = strapi.db.config.models.find( model => model.collectionName === 'clients' );
    return model.attributes;
  },

Where clients is replaced by the plural name of your content-type.

Algo answered 27/1, 2023 at 17:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.