# memo **Repository Path**: luckythc/memo ## Basic Information - **Project Name**: memo - **Description**: mongodb的restful服务 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-30 - **Last Updated**: 2025-12-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Dynamic CRUD API A Node.js API service that dynamically converts HTTP requests to MongoDB CRUD operations. This service allows you to perform CRUD operations on any MongoDB collection without the need to pre-define models or schemas. ## Features - **Automatic Database Connection**: Connects to MongoDB on startup - **Universal CRUD Endpoint**: Single POST endpoint for all CRUD operations - **Dynamic Collection Support**: Works with any collection name without pre-definition - **Smart ID Handling**: Automatically converts string IDs to MongoDB ObjectId - **Pagination and Sorting**: Built-in support for paginated results and sorting - **Batch Operations**: Support for bulk create and update operations - **Associated Queries (JOIN)**: Support for multi-condition join operations between collections - **WeChat Login**: WeChat Mini Program login with JWT token authentication - **Token Authentication**: Secure API access with JWT tokens - **Development Mode**: Fixed token support for development environment testing - **Cross-Origin Support**: CORS enabled for easy frontend integration ## Tech Stack - Node.js - Express.js - MongoDB - Mongoose ## Getting Started ### Prerequisites - Node.js (v14 or higher) - MongoDB instance (configured in `config.js`) ### Installation 1. Install dependencies ```bash npm install ``` 2. Start the server ```bash npm start ``` The server will start on port 3003 by default. ## Configuration Edit `config.js` to set your MongoDB connection details and WeChat app credentials: ```javascript module.exports = { env: 'development', db: { host: '139.196.173.214', port: 27101, username: 'admin', password: 'admin2025', authSource: 'admin', database: 'wass' }, server: { port: 3003 }, wechat: { appId: 'your_wechat_appid', appSecret: 'your_wechat_appsecret', tokenSecret: 'your_token_secret_key', tokenExpiresIn: '7d' }, dev: { fixedToken: 'dev_token_123456', fixedUserId: '000000000000000000000001', fixedOpenid: 'dev_openid_12345' } }; ``` ### Environment Configuration - `env`: Environment setting ('development' or 'production') - In development mode, you can use a fixed token for testing without WeChat login ### WeChat Configuration - `appId`: Your WeChat Mini Program AppID - `appSecret`: Your WeChat Mini Program AppSecret - `tokenSecret`: Secret key for JWT token signing - `tokenExpiresIn`: Token expiration time (default: 7 days) ### Development Mode In development mode (`env: 'development'`), you can use a fixed token for API testing: ```bash Authorization: Bearer dev_token_123456 ``` This token is configured in `config.js` under the `dev` section: - `fixedToken`: Fixed token for development - `fixedUserId`: User ID associated with the dev token - `fixedOpenid`: OpenID associated with the dev token **Note:** For production, set `env: 'production'` to disable the fixed token and enforce WeChat authentication. ## API Usage ### Authentication All CRUD API requests require authentication. You must include the JWT token in the request header: ```bash Authorization: Bearer ``` ### WeChat Login Before using the CRUD API, you need to obtain a JWT token through WeChat login. **Endpoint:** `POST /auth/wechat/login` **Request Body:** ```json { "code": "wx_login_code" } ``` **Response:** ```json { "success": true, "message": "登录成功", "data": { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "openid": "oXYZ...", "userId": "695293a8b4f8d2bb0c0d04d6" } } ``` **Error Response:** ```json { "success": false, "message": "微信登录失败: invalid code", "errcode": 40029 } ``` ### Get User Info Get current user information. **Endpoint:** `GET /auth/user` **Headers:** ```bash Authorization: Bearer ``` **Response:** ```json { "success": true, "data": { "_id": "695293a8b4f8d2bb0c0d04d6", "openid": "oXYZ...", "nickname": "用户昵称", "avatarUrl": "https://...", "createdAt": "2025-12-30T00:00:00.000Z", "updatedAt": "2025-12-30T00:00:00.000Z" } } ``` ### Base URL All CRUD requests are sent to: ```script POST http://localhost:3003/api ``` **Headers:** ```bash Authorization: Bearer Content-Type: application/json ``` ### Request Body Format ```json { "collection": "your_collection_name", "action": "create|read|update|delete", "data": { /* Optional: Data for create/update operations */ }, "query": { /* Optional: Query conditions for read/update/delete */ }, "options": { /* Optional: Additional options */ } } ``` ### Action Types #### 1. Create Create single or multiple documents. **Single Document:** ```json { "collection": "users", "action": "create", "data": { "name": "John Doe", "email": "john@example.com" } } ``` **Multiple Documents:** ```json { "collection": "users", "action": "create", "data": [ { "name": "User 1", "email": "user1@example.com" }, { "name": "User 2", "email": "user2@example.com" } ] } ``` #### 2. Read Read documents with optional query, pagination, and sorting. **Basic Read:** ```json { "collection": "users", "action": "read" } ``` **With Query:** ```json { "collection": "users", "action": "read", "query": { "age": { "$gt": 25 } } } ``` **With Pagination and Sorting:** ```json { "collection": "users", "action": "read", "options": { "page": 1, "limit": 10, "sort": { "createdAt": -1 } } } ``` **With Associated Queries (JOIN):** ```json { "collection": "orders", "action": "read", "query": {}, "options": { "joins": [ { "from": "users", "localField": "userId", "foreignField": "_id", "as": "user" } ] } } ``` #### 3. Update Update single or multiple documents. **Single Document:** ```json { "collection": "users", "action": "update", "query": { "_id": "695293a8b4f8d2bb0c0d04d6" }, "data": { "age": 31 } } ``` **Multiple Documents:** ```json { "collection": "users", "action": "update", "query": { "status": "active" }, "data": { "lastLogin": "2025-12-30T00:00:00.000Z" }, "options": { "multi": true } } ``` #### 4. Delete Delete single or multiple documents. **Single Document:** ```json { "collection": "users", "action": "delete", "query": { "_id": "695293a8b4f8d2bb0c0d04d6" } } ``` **Multiple Documents:** ```json { "collection": "users", "action": "delete", "query": { "status": "inactive" } } ``` ### Health Check ```script GET http://localhost:3003/health ``` ## Associated Queries (JOIN) The API supports MongoDB aggregation pipeline with `$lookup` for joining collections. ### Join Parameters When performing a read operation, you can specify joins in the `options.joins` array: ```json { "collection": "orders", "action": "read", "query": {}, "options": { "joins": [ { "from": "users", "localField": "userId", "foreignField": "_id", "as": "user", "joinType": "left", "query": {}, "unwind": true, "preserveNull": true } ] } } ``` ### Join Options | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `from` | string | Required | Target collection name | | `localField` | string | Required | Field in current collection | | `foreignField` | string | Required | Field in target collection | | `as` | string | Required | Name for joined results | | `joinType` | string | "left" | Join type: "left" or "inner" | | `query` | object | {} | Additional query conditions on joined data | | `unwind` | boolean | true | Whether to unwind the joined array | | `preserveNull` | boolean | true | Whether to preserve null values | ### Join Examples #### 1. Basic Left Join ```json { "collection": "orders", "action": "read", "query": {}, "options": { "joins": [ { "from": "users", "localField": "userId", "foreignField": "_id", "as": "user" } ] } } ``` #### 2. Multi-Condition Join ```json { "collection": "orders", "action": "read", "query": {}, "options": { "joins": [ { "from": "users", "localField": "userId", "foreignField": "_id", "as": "user", "query": { "user.status": "active", "user.role": "admin" } } ] } } ``` #### 3. Inner Join ```json { "collection": "orders", "action": "read", "query": {}, "options": { "joins": [ { "from": "users", "localField": "userId", "foreignField": "_id", "as": "user", "joinType": "inner", "query": { "user.status": "active" } } ] } } ``` #### 4. Multiple Joins ```json { "collection": "orders", "action": "read", "query": {}, "options": { "joins": [ { "from": "users", "localField": "userId", "foreignField": "_id", "as": "user" }, { "from": "products", "localField": "productId", "foreignField": "_id", "as": "product" } ] } } ``` #### 5. Join with Pagination and Sorting ```json { "collection": "orders", "action": "read", "query": {}, "options": { "page": 1, "limit": 10, "sort": { "total": -1 }, "joins": [ { "from": "users", "localField": "userId", "foreignField": "_id", "as": "user" } ] } } ``` #### 6. Join Without Unwinding ```json { "collection": "orders", "action": "read", "query": {}, "options": { "joins": [ { "from": "users", "localField": "userId", "foreignField": "_id", "as": "user", "unwind": false } ] } } ``` ### Join Response Example ```json { "success": true, "action": "read", "collection": "orders", "result": { "total": 3, "page": 1, "limit": 100, "data": [ { "_id": "695293a8b4f8d2bb0c0d04d6", "userId": "695293a8b4f8d2bb0c0d04d5", "productId": "695293a8b4f8d2bb0c0d04d7", "quantity": 2, "total": 11998, "status": "completed", "user": { "_id": "695293a8b4f8d2bb0c0d04d5", "name": "张三", "email": "zhangsan@example.com", "status": "active", "role": "admin" } } ] } } ``` ## Response Format All responses follow this format: ```json { "success": true|false, "action": "create|read|update|delete", "collection": "your_collection_name", "result": { /* Operation result */ } } ``` **Example Response:** ```json { "success": true, "action": "create", "collection": "users", "result": { "acknowledged": true, "insertedId": "695293a8b4f8d2bb0c0d04d6" } } ``` ## Testing Run the test scripts to verify functionality: ```bash # Test CRUD operations with WeChat authentication node test-crud.js # Test WeChat login and authentication node test-auth.js # Test development mode fixed token node test-dev-token.js ``` ## Project Structure ```dict dynamic-crud-api/ ├── config.js # Configuration ├── db/ │ └── connect.js # Database connection ├── controllers/ │ ├── crudController.js # CRUD operations │ └── wechatController.js # WeChat login controller ├── middleware/ │ └── auth.js # Authentication middleware ├── routes/ │ └── index.js # Route definitions ├── server.js # Main entry point ├── test-crud.js # CRUD operations test script ├── test-auth.js # WeChat authentication test script ├── test-dev-token.js # Development mode fixed token test script ├── api-docs.html # API documentation ├── package.json # Dependencies └── README.md # This file ``` ## License ISC