Web Services Best Practices

CMS recommends that service developers adhere to the following recommended practices to ensure the most effective implementation of Web Services.

Implementation Independent

CMS prefers technology-independent implementations. Implementations should follow these recommended practices, regardless of chosen implementation technology.

Consider Using Enterprise Messaging and ESB

For Java-based applications, Java Message Service (JMS) is the preferred mechanism for writing programs that use enterprise messaging because it is the Java Enterprise Edition (EE) standard and has strong vendor support. Because it is an interface specification, application code becomes more portable. Given that JMS does not standardize the implementation protocol, it is necessary to use the same manufacturer’s JMS implementation library on both sides of the channel. Unfortunately, this reduces JMS’s platform independence and flexibility. There are industry initiatives in place to address this, such as AMQP.

For other platforms, such as native IBM Mainframe z/OS or Microsoft.NET, product-specific APIs may be used.

For more information about enterprise messaging, please consult Application Development, Enterprise Messaging.

Use a Transaction Identifier

By providing a transaction identifier (ID) in the web service request, it becomes easier to track a transaction through its life cycle. Transaction IDs are typically whole numbers. Occasionally, it is helpful to use a compound identifier consisting of additional metadata such as a source system or source server.

Use a Session Identifier to Group-Related Transactions

It is easier to track group transactions, perform metrics, and debug complex transactions when web service requests include a session identifier. A session ID is a grouping mechanism for reporting but is not the same as a session cookie. To prevent vulnerability to session hijacking attacks and session prediction attacks, select a secure means for using a session ID to manage sessions.

Typically, session identifiers are whole numbers. It may be helpful to use a compound identifier consisting of additional metadata such as source system or source server.

Consider a “Heartbeat” Service

A “heartbeat” service — or active monitoring (see The Anatomy of APM — Foundational Elements to a Successful Strategy) — checks that the service delivery platform operates correctly without having to process a synthetic” transaction. This is a lightweight service, intended to be called frequently without impacting the capacity of the system.

Consider a Synthetic Transaction

Synthetic transactions verify correct integration of a newly installed system with dependent services. These transactions also monitor “heartbeats” as well as throughput in production systems.

Synthetic transactions present at least two known perils: (1) misuse because of security vulnerability, and (2) potential to skew monitoring statistics if issued in sufficient quantities. It is crucial to achieve a secure design for these transactions.

CMS recommends disabling synthetic transactions during installation (default mode). During production, synthetic transactions must be secure and minimize application load while still providing meaningful business reporting of application functionality.

Application business owners must approve the use of synthetic transactions in production.

Consider for a Mechanism for Production Connectivity Validation

Production interface validation allows external parties to validate connectivity to the service. External parties could connect to the CMS service and submit a small number of specially identified transactions to prove correctly established connectivity and that CMS is receiving transactions. Depending on the implementation, such a mode allows external parties to ascertain (1) acceptance of the HTTP/S certificates and (2) whether the XML or JSON payloads are minimally valid. CMS recommends limiting the number of these transactions. The goal is to demonstrate that the production systems can communicate.

One possible mechanism for this purpose is using a “flag” to identify the transaction for special handling. This mechanism is neither a test capability nor a way to provide testing capabilities to external parties. Testing capabilities should be provided with a separate, designated test system that meets CMS rules for production data management (including but not limited to handling PII, PHI, and sensitive data).

Avoid Programming Language-Dependent Serialization

Many programming languages (such as Java and Python) permit serialization operations; however, these are typically language specific. Services requiring language-specific serialization are not reusable by other programming languages. The realization of any short-term productivity gain is therefore lost over the long term because lock-in limits future options. CMS recommends using the JSON or XML serialization formats that have broad adoption by industry. Accordingly, CMS discourages the use of Java Remote Method Invocation (RMI).

SOAP Best Practices

CMS recommends the following best practices for SOAP Web Services.

Use the Least Number of WS-* Standards Necessary to Achieve Your Goals

Although many of the WS-* standards have value, they can affect portability and stability, especially WS-* standards that have not achieved broad market adoption. Choosing a workable subset is a practical solution.

Use Document / Literal WSDL Operations

New WSDL SOAP bindings should employ “Document/Literal” as opposed to Remote Procedure Call (RPC) style (known formally as “RPC/Encoding”). RPC services use the SOAP RPC conventions and SOAP encoding if required. A developer may use any appropriate reference mechanism that meets WS-* standards.

SOAP API Design Best Practices

The following short summary of API design practices, which is neither exhaustive nor exclusive, help make SOAP APIs more reusable, secure, and stable:

  1. Choose platform independence.
  2. Use SOAP Faults, but do not send stack traces back as part of error and exception handling.
  3. Use ISO 8601 (UTC) date and time formats.
  4. Use SAML assertions.
  5. Support Single Sign-On (SSO) when possible,
  6. For large data sets, allow for pagination of results.
  7. Use UTF-8 encoding.
  8. Consider using API Keys.

REST API Design Best Practices

There are numerous sources for REST API Design Best Practices.

A good set of REST best practices appears in the book REST API Design Rulebook. Practical implementation details appear in the book RESTful Web Services Cookbook. Integrity of REST (relative to the original definition) is not as important as security, simplicity, performance, and interoperability; for example, it is permissible to use REST in a RPC manner. The following summary of API design practices, which is neither exhaustive nor exclusive (and inspired by White House, the GSA 18F group, and Microsoft Guidelines) help make REST APIs more reusable, secure, and stable:

  1. Resource Identification by a unique, persistent URI.
  2. API endpoints identify nouns, not verbs.
  3. Platform independence.
  4. Use HTTP error codes but be cautious about revealing internal structures. Do not send stack traces back as part of error and exception handling.
  5. Discovery via description of URI interfaces.
  6. ISO 8601 (UTC) date and time formats.
  7. JSON web tokens (or equivalent).
  8. Support Single Sign-On.
  9. Use of HTTP standard verbs GET, DELETE, HEAD, and PUT only for idempotent operations (defined as one for which the side effects of N>0 identical requests is the same as for a single request). Beware of such as incrementing numbers and changing dates that are not idempotent
  10. For large data sets, allow for pagination of results.
  11. Use UTF-8 encoding.
  12. Consider using API Keys.
  13. Put version numbers in the URL (e.g., api/v2/resource/{id}.json).
  14. API endpoints use HTTP Accept Headers to determine response media type.
  15. Use Cross Origin Resource Sharing (CORS) for security (not JSONP).
  16. Provide mechanism to throttle API.
  17. Consider using a JSON validation scheme such as the one proposed by json-schema.org.