Define messages which identify the remote procedures to execute and also include a fixed set of elements that map directly into the parameters of remote procedures. Have the client send the message to a URI designated for the procedure.
Define messages which are not derived from the signatures of remote procedures. These messages may carry information on specific topics, tasks to execute, and events. Have the client send the message to a designated URI. Once the message is received at the server, examine its contents to determine the correct procedure to execute.
Assign all procedures, instances of domain data, and files a Uniform Resource Identifier (URI). Leverage HTTP as a complete application protocol to define standard service behaviors. Exchange information by taking advantage of standardized media types and status codes when possible.
Allow clients to indicate one or more media type preferences in HTTP request headers. Send requests to services capable of producing responses in the desired format.
Only publish the addresses of a few root web services. Include the addresses of related services in each response. Let clients parse responses to discover subsequent service URIs.
Create a class that identifies a set of related services. Annotate each class method with routing expressions that can be interpreted by a Front Controller.
Create specialized classes that leverage structure-specific APIs to target and move select portions of requests directly to domain layer entities or to a common set of intermediate objects that can be used as input arguments to such entities. Load a particular mapper based on key content found in the request.
Create a web service that uses a specialized Datasource Provider. Leverage developer tools that generate datasource metadata and produce controllers that not only encapsulate and interpret the rules for request processing, but also direct the actions of Datasource Providers and Message Formatters.
Encapsulate common business logic in domain layer entities that exist outside of the web service. Limit the logic within web services to algorithms that direct the activities of these entities.
Create command objects that fully encapsulate common request processing logic. Instantiate and invoke these commands from within the web service, or forward them to an asynchronous background process
Use a workflow engine to manage the life cycle and execution of tasks within complex or long-running business processes. Identify a web service that will trigger each logical business process. Use callback services to receive additional data for these long-running processes, and forward messages from these callback services to the workflow engine.
Create a library or set of classes that encapsulates the logic a client must implement in order to use a group of related services. Create a high-level interface that abstracts the details of this logic, thereby making the classes easier to use.
Produce a standardized and machine-readable description of related services that identifies URIs, logical operations, messages, server methods, and usage policies.
Dispatch requests on a separate thread of execution apart from the main client thread. Wait for the response on this thread while attending to other matters on the main thread.
Design the client such that common connectivity exceptions are caught. When a connection error occurs, reconnect to the service and resend the request. Limit the number of times such attempts are made. Include a unique identifier in each request so that the service can identify duplicate requests. Alternatively, send the request to a unique URI designated for the specific request.
Client developers write integration tests that express the client's expectations of a service API. These tests are given to the service owner, who incorporates them into the service's test suite.