Node.js结合Swagger实现MongoDB按createdBy参数查询的技术咨询
Alright, let's tackle this problem step by step. First, let's break down what's going wrong with your current setup and outline the best solutions for your React Native + Swagger environment:
Why Your Current Setup Isn't Working
- Swagger Path Syntax Error: Your path definition
/location/getLocation/:createdByuses Express-style parameter notation, but Swagger requires curly braces{createdBy}to recognize path parameters. This is likely why yourcreatedByvalue is showing up empty. - GET Requests Don't Support Request Bodies: HTTP standards discourage using request bodies for GET calls, and many tools (including Swagger UI) will ignore or drop the request body entirely for GET requests.
Option 1: Fix the Path Parameter Approach (Most RESTful)
This is the cleanest solution if the phone number is the primary identifier for the user's locations.
Step 1: Update Swagger Configuration
Fix the path parameter syntax and remove the invalid requestBody section:
/** * @swagger * /location/getLocation/{createdBy}: * get: * summary: Get all locations for a user by phone number * tags: [Location] * parameters: * - in: path * name: createdBy * required: true * schema: * type: string * description: User's phone number * responses: * 200: * description: Successfully retrieved user locations * content: * application/json: * schema: * type: object * properties: * success: * type: boolean * msg: * type: string * data: * type: array * items: * $ref: '#/components/schemas/Location' * 500: * description: Server error */
Step 2: Verify Controller & Route
Your existing controller code is fine—once Swagger sends the path parameter correctly, req.params.createdBy will hold the phone number:
exports.getLocation = asyncHandler(async (req, res, next) => { const createdBy = req.params.createdBy console.log('created', createdBy) // Now this should log the phone number const locations = await Location.find( {createdBy: createdBy} ) res.status(200).json({ success: true, msg: "Getting all the locations of the user", data: locations }) })
React Native Request Example (Axios)
import axios from 'axios'; const fetchUserLocations = async (phoneNumber) => { try { const response = await axios.get(`https://your-api-domain/location/getLocation/${phoneNumber}`); return response.data; } catch (error) { console.error('Error fetching locations:', error); throw error; } };
Option 2: Use Query Parameters (More Flexible for Filters)
Great if you might add additional filter criteria (like date ranges) later.
Step 1: Update Route & Swagger
Remove the path parameter and define a query parameter instead:
/** * @swagger * /location/getLocation: * get: * summary: Get all locations for a user by phone number * tags: [Location] * parameters: * - in: query * name: createdBy * required: true * schema: * type: string * description: User's phone number * responses: * 200: * description: Successfully retrieved user locations * content: * application/json: * schema: * type: object * properties: * success: * type: boolean * msg: * type: string * data: * type: array * items: * $ref: '#/components/schemas/Location' * 500: * description: Server error */
Update your route to remove the path parameter:
router.get("/getLocation", getLocation)
Step 2: Modify Controller to Use Query Params
exports.getLocation = asyncHandler(async (req, res, next) => { const createdBy = req.query.createdBy console.log('created', createdBy) const locations = await Location.find( {createdBy: createdBy} ) res.status(200).json({ success: true, msg: "Getting all the locations of the user", data: locations }) })
React Native Request Example
const fetchUserLocations = async (phoneNumber) => { try { const response = await axios.get('https://your-api-domain/location/getLocation', { params: { createdBy: phoneNumber } }); return response.data; } catch (error) { console.error('Error fetching locations:', error); throw error; } };
Option 3: Use POST with Request Body (Last Resort)
Only use this if you have a specific reason to avoid URL parameters (note: this breaks REST semantics, as POST is intended for creating resources, not fetching them).
Step 1: Update Route & Swagger
Switch to a POST request and define the request body:
/** * @swagger * /location/getLocation: * post: * summary: Get all locations for a user by phone number * tags: [Location] * requestBody: * required: true * content: * application/json: * schema: * type: object * properties: * createdBy: * type: string * description: User's phone number * responses: * 200: * description: Successfully retrieved user locations * content: * application/json: * schema: * type: object * properties: * success: * type: boolean * msg: * type: string * data: * type: array * items: * $ref: '#/components/schemas/Location' * 500: * description: Server error */
Update your route to use POST:
router.post("/getLocation", getLocation)
Step 2: Modify Controller to Read Request Body
exports.getLocation = asyncHandler(async (req, res, next) => { const createdBy = req.body.createdBy console.log('created', createdBy) const locations = await Location.find( {createdBy: createdBy} ) res.status(200).json({ success: true, msg: "Getting all the locations of the user", data: locations }) })
React Native Request Example
const fetchUserLocations = async (phoneNumber) => { try { const response = await axios.post('https://your-api-domain/location/getLocation', { createdBy: phoneNumber }); return response.data; } catch (error) { console.error('Error fetching locations:', error); throw error; } };
Final Recommendations
- Option 1 is the best choice for your use case (most RESTful, cleanest implementation).
- Option 2 is ideal if you plan to expand the API with additional filters later.
- Option 3 should only be used if you have a strict requirement to avoid URL parameters (remember: HTTPS encrypts the entire request, so URL parameters are secure).
内容的提问来源于stack exchange,提问作者mier23

