RESTful API同一端点复用ID/参数是否合理?日期查询如何设计?
First off, you’re absolutely correct that your initial endpoint pattern (/companies/:id/tickets/:date) isn’t ideal. Let’s walk through the proper way to structure these endpoints while sticking to REST principles:
1. Fetching a Single Ticket by ID
This one is straightforward and actually follows good practice:
- Use
GET /companies/:companyId/tickets/:ticketId - Path parameters here are for identifying a specific, unique resource—a single ticket belonging to a specific company. This aligns perfectly with REST’s focus on resource-oriented design.
2. Filtering Tickets by Date (or Other Criteria)
Here’s where the original approach falls short. Dates are filtering criteria, not unique resource identifiers—one date can correspond to multiple tickets. Instead of shoving the date into the path, use query parameters:
- For a single date:
GET /companies/:companyId/tickets?date=2024-05-20 - For a date range (even more flexible):
GET /companies/:companyId/tickets?startDate=2024-05-01&endDate=2024-05-31
Why Not Use a Payload for Filtering?
You mentioned hesitation about using a payload for this, and that’s well-founded. Here’s why:
GETrequests (which are for retrieving data) shouldn’t include a request body. While the HTTP spec technically allows it, most tools, caching layers, and API clients don’t support or expect it. It breaks convention and can lead to unexpected behavior.- Query parameters are designed exactly for this use case: modifying the scope of a collection request without altering the core resource path. They’re also self-documenting and easy to test directly in a browser.
What’s Wrong with /companies/:id/tickets/:date?
- Semantically, this endpoint implies there’s a single "ticket resource" identified by a date, which isn’t true—you’re fetching a collection of tickets from that date.
- It’s inflexible. If you later need to add more filters (like ticket status, priority, or assignee), you’d end up with messy, unmanageable paths like
/companies/:id/tickets/:date/:status, which doesn’t scale.
Final Recommended Endpoint Structure
- Get all tickets for a company:
GET /companies/:companyId/tickets - Get a single specific ticket:
GET /companies/:companyId/tickets/:ticketId - Get tickets filtered by date (or other criteria):
GET /companies/:companyId/tickets?date=YYYY-MM-DD(add more query params as needed)
This structure keeps your API clean, intuitive, and scalable—plus it follows widely accepted REST conventions that other developers will immediately understand.
内容的提问来源于stack exchange,提问作者Erick Gallani

