含依支付类型转为必填的可选参数的请求体是否符合REST规范?
Great question! Let’s break this down and figure out how to structure your payment API in a way that aligns with REST best practices.
First, let’s clarify: REST doesn’t enforce rigid rules that forbid adjusting required parameters based on context—instead, it focuses on consistent resource modeling and clear state transitions. So your approach can absolutely be compliant, as long as you handle it thoughtfully. Here’s how to make it work well:
1. Be explicit about parameter rules (and document them thoroughly)
For each payment type (e.g., card, bank_transfer), clearly define which fields are required in your API docs. For example:
- When
type=card(in your path),amountandcard_details(includingnumberandexpiry) are mandatory;bank_detailscan be omitted or ignored. - When
type=bank_transfer,amountandbank_details(includingbsbandaccount_number) are mandatory;card_detailsis optional/ignored.
This clarity ensures API consumers know exactly what to send for each scenario.
2. Consider refining your endpoint design
Your current endpoint POST /clients/{id}/payments/{type} uses type as a path parameter, which is acceptable—but there’s a more RESTful alternative: treat the payment type as an attribute of the payment resource itself. Instead, use:POST /clients/{id}/payments
And include a type field in your request body, like this:
{ "amount": 250, "type": "card", "card_details": { "number": "4111-1111-1111-1111", "expiry": "06/27" }, "reference": "INV-789" }
This aligns better with REST’s focus on resources: a payment is a single resource, and its type is just one of its properties. It also simplifies validation logic since you can check the type field directly in the request body.
3. Optimize request body structure for clarity
Instead of having top-level card_details and bank_details fields (which can feel cluttered), nest them under a payment_method object. This makes the structure more intuitive and easier to validate:
{ "amount": 500, "reference": "ORD-456", "payment_method": { "type": "bank_transfer", "bank_details": { "bsb": "123-456", "account_number": "987654321" } } }
This way, only the relevant payment details are included, reducing ambiguity.
4. Handle errors gracefully
When a client sends a request missing required fields for the specified payment type, return a 400 Bad Request status code with a clear, human-readable error message. For example:
{ "error": "Invalid request", "message": "For payment type 'bank_transfer', 'payment_method.bank_details.bsb' and 'payment_method.bank_details.account_number' are required." }
This helps developers debug issues quickly without guessing.
Final takeaway
REST is flexible—adjusting required parameters based on payment type is totally acceptable, as long as you’re consistent, transparent, and provide clear feedback to API consumers. The key is to model your resources logically and document every scenario thoroughly.
内容的提问来源于stack exchange,提问作者Rohith Mohan

