Web service messages should be chunky, not chatty. Message-oriented, not call-oriented.
A request or command message should contain, at a bare minimum, enough information to:
- Validate the caller (authentication/authorization).
- Validate the transaction (for example, an update request in an optimistic concurrency environment might require the original version number)
- Execute the transaction (identifiers, search parameters, etc.)
In addition, there will usually be several parameters/elements that you will want to have as optional but not required:
Lists of sub-requests, with a client-supplied correlation ID. For any given operation, don't require the client to make requests one by one; instead, allow them to cram it all into a single message, and make sure you repeat their correlation IDs in the response. This is critically important in high-latency environments. (Correlation IDs should of course be optional, like the list itself).
The data type (for REST especially) - allow clients to specify XML, JSON, etc.
Control over the size and shape of the response message, especially if the response will be very large and/or contain many elements. At a minimum, provide a way to throttle the maximum number of results. Sorting and paging options are better. Some services - for example Salesforce - also provide a "query ID" that can be used to quickly retrieve pages of a result.
If it's likely to make a difference in performance, you might also consider allowing clients to indicate the level of nesting and/or which relationships to load, using a sensible default (generally all or none).
A return address (for one-way messages).
Timeouts, error-handling strategies, log settings, or anything else that might be of particular importance for a long-running transaction. (Again, use sensible defaults, and validate the inputs!)
Some services will supply clients with an area to just stuff in whatever user data they want, either as a string or as an XML element. Think of this as the "memo" line on a cheque. It's especially useful in one-way messaging scenarios.
I can't emphasize strongly enough that this second list of options needs to be optional and only used for messages that actually benefit from it. You don't want to confuse clients with a bewildering array of seemingly pointless options.
Finally, try to keep information that is common to all messages (especially credentials) in the headers, not the body. If you have information that's common to many messages but not necessarily all (sorting/paging being one common example), then considering abstracting it into its own data type (parameter object). That way the client can reuse the same settings over and over again if it wants to.
Please don't require all sorts of checks and balances like names that have to match IDs, or session IDs, or checksums, or control totals, or whatever. You have to trust your clients with the privileges they've been given. If you don't trust them to send correct data (according to their own requirements) then you have a business problem to solve, not a technical one.