Bringing the power of Drupal Views to Strapi - Build custom APIs visually, without writing a single line of code!
Remember the power and flexibility of Drupal Views? The ability to create complex, filtered, and sorted data presentations through a visual interface? This plugin brings that same revolutionary approach to Strapi.
Just as Drupal Views transformed how developers and content managers create data displays in Drupal, the Strapi Custom API Builder empowers you to:
- ๐จ Visually design APIs through an intuitive interface
- ๐ Apply complex filters without writing query logic
- ๐ Sort and paginate data with simple selections
- ๐ Handle relationships elegantly and automatically
- โก Generate production-ready endpoints instantly
- ๐ก๏ธ Maintain security with built-in validation and sanitization
No more manually writing controllers, routes, or query builders. Focus on what data you want to expose, and let the plugin handle the rest.
- Features
- Installation
- Quick Start Guide
- Step-by-Step Tutorial
- API Features
- Advanced Usage
- Troubleshooting
- Contributing
- License
- โ Visual API Builder - Point-and-click interface for creating custom endpoints
- โ Smart Field Selection - Choose exactly which fields to expose
- โ Relationship Management - Automatically handle complex data relationships
- โ Advanced Filtering - 16+ filter operators ($eq, $contains, $gte, etc.)
- โ Multi-field Sorting - Sort by multiple fields with various formats
- โ Flexible Pagination - Page-based and offset-based pagination support
- โ Query Visualization - See your API structure before deployment
- โ Auto-generated Documentation - Each API comes with filter documentation
- โ Schema Validation - Gracefully handles content type changes
- โ Production Ready - Optimized queries with proper sanitization
- ๐ฏ No Code Required - Build complex APIs without writing controllers
- ๐ Live Preview - See example queries and responses in real-time
- ๐ก๏ธ Security First - Built-in validation and sanitization
- ๐ Scalable - Handles large datasets with intelligent pagination
- ๐ง Maintainable - Changes to content types are handled gracefully
- Strapi v5 - (current) - v2.x
- Strapi v4 - (legacy) - v1.x
- Strapi v5.0.0 or higher
- Node.js 18.x or 20.x
- npm or yarn package manager
# Create a new Strapi project using npx (recommended)
npx create-strapi@latest my-project --quickstart --skip-cloud
# The command will prompt you - answer 'N' to skip anonymous telemetry
# Then it will install dependencies and set up your project
# Navigate to your project once installation is complete
cd my-projectNote: The --quickstart flag creates a project with SQLite database for quick setup. The --skip-cloud flag skips the Strapi Cloud setup prompts.
# Using npm
npm install strapi-plugin-custom-api
# Or using yarn
yarn add strapi-plugin-custom-apiIMPORTANT: You must also install these UI dependencies for Strapi v5:
npm install @strapi/design-system @strapi/icons
# Or using yarn
yarn add @strapi/design-system @strapi/iconsCreate or update config/plugins.js:
module.exports = {
'custom-api': {
enabled: true,
config: {
// Add any custom configuration here
}
}
};# Rebuild the admin panel
npm run build
# Start Strapi in development mode
npm run develop
# Or with npx (if strapi command is not available)
npx strapi developThe server will start and open your browser to http://localhost:1337/admin where you'll need to create your first admin user.
After starting Strapi, navigate to your admin panel (typically http://localhost:1337/admin). You'll find "Custom Api Builder" in the left sidebar menu.
- Click on "Custom Api Builder" in the sidebar
- Click the "Create new API" button
- Fill in the basic information:
- Name: Give your API a descriptive name (e.g., "Product Catalog")
- Slug: This will be auto-generated (e.g., "product-catalog")
- Content Type: Select the content type to query
Choose which fields to include in your API response:
- โ Check the fields you want to expose
- ๐ Use the search bar to find specific fields quickly
- ๐ท๏ธ Filter by field type using the type badges
Enable the features you need:
- Filtering: Allow clients to filter results
- Sorting: Enable result ordering
- Pagination: Add pagination support
- Click "Save" to create your API
- Your endpoint is immediately available at:
GET /api/custom-api/your-slug
Let's build a real-world example: a product catalog API with filtering, sorting, and pagination.
First, ensure you have a Product content type with these fields:
- name (Text)
- description (Rich Text)
- price (Number)
- category (Relation to Category)
- inStock (Boolean)
- featured (Boolean)
- Navigate to Custom Api Builder
- Click "Create new API"
- Enter:
- Name: "Product Catalog API"
- Slug: Will auto-generate as "product-catalog-api"
- Content Type: Select "Product"
Check the following fields:
- โ name
- โ description
- โ price
- โ category
- โ inStock
- โ featured
For the category relationship:
- Select which category fields to include (e.g., name, slug)
- The plugin automatically handles the join queries
- โ Enable Filtering
- โ Enable Sorting
- โ Enable Pagination
Your API is now available! Here are example queries:
# Get all products
GET /api/custom-api/product-catalog-api
# Filter by price range
GET /api/custom-api/product-catalog-api?price[$gte]=10&price[$lte]=100
# Filter by category and stock
GET /api/custom-api/product-catalog-api?category.name=Electronics&inStock=true
# Sort by price (ascending) and name (descending)
GET /api/custom-api/product-catalog-api?sort=price,-name
# Paginate results
GET /api/custom-api/product-catalog-api?page=2&pageSize=20
# Combine everything
GET /api/custom-api/product-catalog-api?featured=true&price[$lte]=50&sort=-createdAt&page=1&pageSize=10The plugin supports 16 filter operators:
| Operator | Description | Example |
|---|---|---|
$eq |
Equals | ?name[$eq]=iPhone |
$ne |
Not equals | ?status[$ne]=draft |
$contains |
Contains substring | ?title[$contains]=guide |
$notContains |
Doesn't contain | ?title[$notContains]=draft |
$in |
In array | ?category[$in]=tech,mobile |
$notIn |
Not in array | ?status[$notIn]=draft,archived |
$lt |
Less than | ?price[$lt]=100 |
$lte |
Less than or equal | ?price[$lte]=100 |
$gt |
Greater than | ?views[$gt]=1000 |
$gte |
Greater than or equal | ?rating[$gte]=4 |
$between |
Between two values | ?price[$between]=10,100 |
$startsWith |
Starts with | ?title[$startsWith]=How |
$endsWith |
Ends with | ?email[$endsWith]=@gmail.com |
$null |
Is null | ?deletedAt[$null]=true |
$notNull |
Is not null | ?publishedAt[$notNull]=true |
$or |
OR condition | ?$or[0][name]=iPhone&$or[1][name]=Samsung |
Multiple sorting formats are supported:
# Comma-separated
?sort=price,-createdAt
# Array format
?sort[]=price&sort[]=-createdAt
# Object format
?sort[price]=asc&sort[createdAt]=desc
# With symbols
?sort=+price,-createdAtTwo pagination styles:
# Page-based (recommended)
?page=2&pageSize=20
# Offset-based
?offset=20&limit=20Response includes metadata:
{
"data": [...],
"meta": {
"pagination": {
"page": 2,
"pageSize": 20,
"total": 150,
"pageCount": 8
}
}
}Each API automatically gets a documentation endpoint:
GET /api/custom-api/your-slug/filtersReturns available filters, operators, and examples specific to your API.
The plugin intelligently handles relationships:
// One-to-Many: Returns array
{
"product": {
"name": "iPhone",
"categories": [
{ "id": 1, "name": "Electronics" },
{ "id": 2, "name": "Mobile" }
]
}
}
// Many-to-One: Returns single object
{
"product": {
"name": "iPhone",
"manufacturer": { "id": 1, "name": "Apple" }
}
}# Products in multiple categories with price range
?category.slug[$in]=electronics,computers&price[$between]=100,500
# Featured products or products with high ratings
?$or[0][featured]=true&$or[1][rating][$gte]=4.5
# Products without images
?images[$null]=true
# Recent products in stock
?inStock=true&createdAt[$gte]=2024-01-01// Using fetch
const response = await fetch('/api/custom-api/product-catalog-api?' + new URLSearchParams({
'category.slug': 'electronics',
'price[$lte]': '500',
'sort': '-rating',
'page': '1',
'pageSize': '20'
}));
const { data, meta } = await response.json();
// Using axios
const { data } = await axios.get('/api/custom-api/product-catalog-api', {
params: {
'featured': true,
'price[$between]': '10,100',
'sort': ['price', '-createdAt'],
'page': 1,
'pageSize': 20
}
});Solution: Rebuild the admin panel
npm run build
npm run develop
# Or if the strapi command is not found:
npx strapi build
npx strapi developSolution: Create at least one content type in your Strapi project first.
Possible causes:
- The slug might be incorrect
- The API might not be published
- Check the exact endpoint:
/api/custom-api/your-slug
Check:
- Field names are correct (case-sensitive)
- Operators are properly formatted (e.g.,
[$contains]) - Fields are included in the API configuration
Optimize by:
- Using pagination (
pageSizeparameter) - Adding database indexes on filtered fields
- Limiting the number of fields returned
- Using specific filters to reduce dataset size
Enable debug logging in your Strapi configuration:
// config/server.js
module.exports = {
// ... other config
logger: {
level: 'debug',
}
};Solution: Use npx to run Strapi commands
# Instead of: strapi develop
npx strapi develop
# Instead of: strapi build
npx strapi buildSolution: Ensure all required dependencies are installed
# Clean install
rm -rf node_modules package-lock.json
npm install
# Install missing UI dependencies
npm install @strapi/design-system @strapi/iconsSolution: Strapi runs on port 1337 by default
# Kill process on port 1337
lsof -ti:1337 | xargs kill -9
# Or run on different port
PORT=8080 npm run developWe welcome contributions! Here's how you can help:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
# Clone the repository
git clone https://github.com/vivmagarwal/strapi-plugin-custom-api-builder.git
# Install dependencies
npm install
# Run tests
npm test
# Link for local development
npm link
# In your Strapi project
npm link strapi-plugin-custom-apiThis project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by the legendary Drupal Views module
- Built for the amazing Strapi community
- Special thanks to all contributors
- @vivmagarwal - Original author
- @cjboco - Contributor
- ๐ง Email: vivmagarwal@gmail.com
- ๐ Issues: GitHub Issues
- ๐ฌ Discussions: GitHub Discussions
Made with โค๏ธ by Vivek M. Agarwal
Bringing the power of visual API building to Strapi, one endpoint at a time.