RESTful API Routes
EverShop provides a comprehensive system for building RESTful API endpoints that power your store's backend functionality. This document explains how to create, structure, and secure these endpoints.
Before diving into API routes, it's recommended to familiarize yourself with the module structure to understand how modules are organized in EverShop.
API Organization
EverShop's RESTful APIs are located in the api
folder of each module. Below is an example of the API structure in the catalog
module:
catalog
├── api
│ ├── createProduct
│ │ ├── ... // Middleware functions
│ │ └── route.json
│ ├── updateProduct
│ │ ├── ... // Middleware functions
│ │ └── route.json
│ ├── createCategory
│ │ ├── ... // Middleware functions
│ │ └── route.json
│ ├── updateCategory
│ │ ├── ... // Middleware functions
│ │ └── route.json
│ ├── createAttribute
│ │ ├── ... // Middleware functions
│ │ └── route.json
│ └── updateAttribute
│ ├── ... // Middleware functions
│ └── route.json
API Folder Structure
The api
folder contains the following organization:
-
global
- Contains middleware functions that apply to all API endpoints. For example, theauth
middleware that handles authentication for all secured endpoints. -
<apiID>
- Individual folders representing specific API endpoints. For example, thecreateProduct
folder contains all the components needed for the product creation API.
Single API Endpoint Structure
Each API endpoint folder contains middleware functions and a route definition file. Here's an example structure:
├── createProduct
│ ├── [context]bodyParser[auth].ts
│ ├── saveProduct.ts
│ └── route.json
The middleware functions handle the request processing, while the route.json
file defines how the endpoint is accessed.
API Route Definition
Every API endpoint requires a route.json
file that specifies the HTTP methods, path, and access restrictions. For example, here's the route definition for a product deletion API:
{
"methods": ["DELETE"],
"path": "/products/:id",
"access": "private"
}
The folder name is used as the routeId, so ensure each folder name is unique and contains only URL-safe characters. The routeId is important for correctly routing and identifying API endpoints.
For more detailed information on routing patterns and options, refer to the routing system documentation.
API Authentication
The access
property in the route.json
file controls endpoint security:
public
- The endpoint can be accessed without authenticationprivate
- The endpoint requires authentication (admin user credentials)
For security best practices, endpoints without an explicitly defined access
property are treated as private
by default, requiring authentication to access.
API Request Data Validation
EverShop allows you to define validation schemas for API request data using a payloadSchema.json
file in the API endpoint folder. This ensures that incoming data meets your requirements before processing.
Here's an example schema for product creation:
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"short_description": {
"type": "string"
},
"url_key": {
"type": "string",
"pattern": "^\\S+$"
},
"meta_title": {
"type": "string"
},
"meta_description": {
"type": "string"
},
"meta_keywords": {
"type": "string"
},
"status": {
"type": ["integer", "string"],
"enum": [0, 1, "0", "1"]
},
"sku": {
"type": "string"
},
"price": {
"type": ["string", "number"],
"pattern": "^\\d+(\\.\\d{1,2})?$"
},
"weight": {
"type": ["string", "number"],
"pattern": "^[0-9]+(\\.[0-9]{1,2})?$"
},
"qty": {
"type": ["string", "number"],
"pattern": "^[0-9]+$"
},
"manage_stock": {
"type": ["string", "number"],
"enum": [0, 1, "0", "1"]
},
"stock_availability": {
"type": ["string", "number"],
"enum": [0, 1, "0", "1"]
},
"group_id": {
"type": ["string", "integer"],
"pattern": "^[0-9]+$"
},
"visibility": {
"type": ["integer", "string"],
"enum": [0, 1, "0", "1"]
},
"images": {
"type": "array",
"items": {
"type": "string"
}
},
"attributes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"attribute_code": {
"type": "string"
},
"value": {
"type": ["string", "array"],
"items": {
"type": "string"
}
}
}
}
},
"categories": {
"type": "array",
"items": {
"type": ["string", "integer"],
"pattern": "^[0-9]+$"
}
},
"options": {
"type": "array",
"items": {
"type": "object",
"properties": {
"option_name": {
"type": "string"
},
"option_type": {
"type": "string",
"enum": ["select", "multiselect"]
},
"is_required": {
"type": ["string", "integer"],
"enum": [0, 1, "0", "1"],
"default": 0
},
"values": {
"type": "array",
"items": {
"type": "object",
"properties": {
"value": {
"type": "string"
},
"extra_price": {
"type": ["string", "number"],
"pattern": "^\\d+(\\.\\d{1,2})?$"
}
}
}
}
},
"required": ["option_name", "option_type", "values"],
"additionalProperties": true
}
}
},
"required": [
"name",
"meta_title",
"url_key",
"status",
"sku",
"qty",
"price",
"weight",
"group_id",
"visibility"
],
"additionalProperties": true
}
When a request is made to the API endpoint, the request data is automatically validated against this schema. If validation fails, an appropriate error response is sent to the client with details about the validation issues.
EverShop uses Ajv JSON schema validator for request payload validation, providing robust and flexible validation capabilities.
API Middleware Functions
EverShop's API endpoints are powered by middleware functions that process requests sequentially. You can create as many middleware functions as needed for each API endpoint, allowing for modular and maintainable code.
For more details on how middleware functions work in EverShop, refer to the middleware system documentation.
Sharing Middleware Across Endpoints
For efficiency, you may need to reuse middleware functions across multiple API endpoints. EverShop provides a convenient way to share middleware:
-
Endpoint-Specific Sharing: Create a special folder named after the endpoints that should share middleware (e.g.,
createProduct+updateProduct
) in theapi
directory. Place shared middleware functions in this folder, and they'll be executed for both endpoints. -
Global Sharing: For middleware that should run for all API endpoints, place it in the
api/global
folder.
These special shared middleware folders should contain only middleware functions without a route.json
file, as they don't define endpoints themselves but enhance existing ones.
Best Practices for API Development
When developing APIs for EverShop, consider these best practices:
- Proper Validation: Always define comprehensive validation schemas for request data
- Access Control: Set appropriate
access
levels for your endpoints - Modular Design: Break complex operations into multiple middleware functions
- Error Handling: Provide clear error responses with appropriate HTTP status codes
- Documentation: Comment your code and keep API contracts consistent