Using the REST API

The REST API implements the same messaging model as the Java library, with the exception that connections, sessions, producers, consumers, queue browsers, and temporary destinations are created as resources on the service instance through the REST API.

Topics:

Before you begin using the REST API, review the guidelines in this section as well as the general guidelines in Considerations When Developing Applications That Use Oracle Messaging Cloud Service.

Typical Workflow for Using the REST API

To start using the REST API, refer to the following tasks as a guide:

Task Description More Information

Create a messaging context

Create a messaging context, and manage the lifecycle of messaging contexts through the maximum inactive interval (MII) feature.

Creating and Managing Messaging Contexts

Create a connection

Create connections before sending and receiving messages.

Creating and Managing Connections

Create a message push listener

Create listeners to push messages to a destination or user-defined URL.

Creating and Managing Message Push Listeners

Create a session

Create sessions before sending or receiving messages.

Creating and Managing Sessions

Create a producer

Create producers to send messages.

Sending Messages

Create a consumer

Create consumers to receive messages.

Receiving Messages

Send a message through a producer

Send messages through producers.

Sending Messages

Receive a message through a consumer

Receive message through consumers.

Receiving Messages

Messaging Context and HTTP Cookies

A messaging context is a container of ephemeral objects like connections, sessions, producers, consumers, temporary destinations, and queue browsers.

A messaging context is identified by the JSESSIONID cookie. The only API specific to a messaging context is the API for getting and setting the maximum inactive interval (MII), which controls the expiration time of the messaging context. When the messaging context expires, all ephemeral objects contained in it are closed and deleted, except for temporary destinations. A temporary destination is closed only if the connection by which the temporary destination was created is closed.

The Oracle Messaging Cloud Service REST API relies critically on the use of JSESSIONID HTTP cookies to identify and reuse messaging contexts between REST API HTTP requests.

At least one messaging context must be created by a client in order to access Oracle Messaging Cloud Service. If an HTTP request does not include a JSESSIONID cookie for an unexpired messaging context, then a new messaging context is created. The HTTP response includes the header X-OC-NEW-MESSAGING-CONTEXT: true if a new messaging context is created. Note that connections and derived objects created in a messaging context cannot be used in other messaging contexts, except for temporary destinations. A temporary destination created in a messaging context can be used in other messaging contexts.

When a messaging context is created through the REST API, the messaging context is assigned an MII. A messaging context expires if it is not accessed for a period of time longer than the associated MII. By default, all messaging contexts have an MII of 5 minutes. The MII for a given messaging context can be increased to a maximum of 15 minutes by the client. The minimum non-zero value of an MII is 1 second. If the MII is set to 0, the messaging context expires immediately.

Each Oracle Messaging Cloud Service instance has a quota of connections that can be created. When using the REST API, it is important to handle JSESSIONID HTTP cookies diligently to manage messaging contexts and their associated connections. If the cookies are not handled, then a new messaging context is created on every HTTP request to the REST API. This can quickly lead to the exhaustion of the instance's connection quota if a connection is created in each messaging context.

In special situations, clients may wish to durably store JSESSIONID HTTP cookies associated with active messaging contexts. For example, if a client machine fails, cookies for active messaging contexts can be lost from non-durable storage, and if the application cannot wait for the messaging context to expire, then it is important to durably store cookies. If cookies are durably stored, the active messaging contexts and their connections can be reached after the client comes back up, as long as those messaging contexts have not expired during the client down time.

Note:

If Cross-Site Request Forgery (CSRF) prevention is enabled for a given messaging context, clients may also wish to durably store the anti-CSRF token associated with the messaging context for the messaging context and associated connections to be reachable when the client is back up. See Cross-Site Request Forgery (CSRF) Prevention for details about how anti-CSRF tokens are used by Oracle Messaging Cloud Service.

Authentication

All HTTP requests to the Oracle Messaging Cloud Service REST API require authentication.

Every HTTP request to Oracle Messaging Cloud Service should supply HTTP Basic Authentication credentials through the Authorization header.

About HTTP Headers

The Oracle Messaging Cloud Service REST API uses various HTTP headers to send and receive information. The names of these headers are written in capital letters throughout, but HTTP headers are required to be treated as case-insensitive.

Any client of the REST API should be implemented so as to treat HTTP header names in Oracle Messaging Cloud Service responses as case-insensitive. HTTP header names may occur multiple times within a single HTTP response, so any client of the REST API should be implemented so as to handle multiple occurrences of a header with the same name (or with the same name except for differences in case) properly.

Cross-Site Request Forgery (CSRF) Prevention

Cross-Site Request Forgery (CSRF) is a malicious attack on HTTP clients whereby destructive operations may be unknowingly made against a web server.

To prevent CSRF attacks, Oracle Messaging Cloud Service generates pseudorandom anti-CSRF tokens for each messaging context.

When a new messaging context is created, a new anti-CSRF token is generated and returned in the messaging context's first HTTP response as the value of the X-OC-ID-TOKEN HTTP header. The token is not returned in subsequent HTTP responses.

Once an anti-CSRF token has been generated, every subsequent HTTP request must include its messaging context's associated token in the X-OC-ID-TOKEN HTTP header. If the token is inaccurate or missing, an HTTP response with status code 400 is returned, and the HTTP request is not processed.

See Understanding Anti-CSRF Measures for more information about the generation and use of anti-CSRF tokens in the Oracle Messaging Cloud Service REST API.

If desired, you can disable the CSRF prevention mechanism in these ways:

  • To disable the mechanism before the connection's anti-CSRF token is generated, pass the X-OC-ID-TOKEN-STATUS HTTP header with the value of disabled on the messaging context's first HTTP request.

  • To disable the mechanism for a messaging context that has already generated an anti-CSRF token, pass the X-OC-ID-TOKEN-STATUS HTTP header with the value of disabled, and also pass the X-OC-ID-TOKEN HTTP header with the value of the token that was generated for the messaging context.

Note:

If anti-CSRF is enabled, see Messaging Context and HTTP Cookies for information about how Oracle Messaging Cloud Service uses JSESSIONID HTTP cookies and why clients may wish to durably store anti-CSRF tokens and cookies associated with active messaging contexts.

Resource Management versus Message Transmission APIs

The operations in the Oracle Messaging Cloud Service REST API can be divided into two functional areas:

  • Resource management: The Resource Management API provides functionality to create and manage destinations, and message push listeners.

  • Message transmission: The Message Transmission API provides functionality to create and manage connections, create and manage sessions, send messages through producers, receive messages through consumers, create and delete durable subscriptions, inspect messages through queue browsers, and create and delete temporary destinations.

Message Types

This section provides information about various message types supported by the REST API.

Topics:

The REST API supports the HTTP message type in addition to all of the JMS message types such as TEXT and BYTES.

When sending a message through the REST API, set the value of the X-OC-MESSAGE-TYPE HTTP header to specify the message's type. The default message type is HTTP.

When messages are sent and received through the REST API, the message body is transmitted as the HTTP request body.

The valid values for the X-OC-MESSAGE-TYPE HTTP header along with any required formatting for the HTTP request body are described in the following sections.

PLAIN

The message has no body.

Note the following rules for a message of this type:

  • When the message is sent through the REST API, the HTTP request's body is ignored.

  • When the message is accessed through the Java library, the message is an object of the class javax.jms.Message that has no body.

  • When the message is received through the REST API, the HTTP response body and Content-Type header are empty.

  • When the message is pushed to a URL by a message push listener, the HTTP request body and Content-Type header are empty.

TEXT

The message's body is a String.

Note the following rules for a message of this type:

  • When the message is sent through the REST API, the HTTP request's body is converted to a String using the encoding specified by the HTTP request's headers.

  • When the message is accessed through the Java library, the message is an object of the class javax.jms.TextMessage.

  • When the message is received through the REST API, the HTTP response's body is encoded with UTF-8 and the Content-Type header is as follows:
    text/plain; charset=UTF-8
  • When the message is pushed to a URL by a message push listener, the HTTP request's body is encoded with UTF-8 and the Content-Type header is as follows:
    text/plain; charset=UTF-8

BYTES

The message's body is an array of bytes.

Note the following rules for a message of this type:

  • When the message is sent through the REST API, the HTTP request's body is handled as an array of bytes.

  • When the message is accessed through the Java library, the message is an object of the class javax.jms.BytesMessage.

  • When the message is received through the REST API, the HTTP response's body is the bytes of the array and the Content-Type is as follows:
    application/octet-stream
  • When the message is pushed to a URL by a message push listener, the HTTP request's body is the bytes of the array and the Content-Type is as follows:
    application/octet-stream

OBJECT

The message's body is a serialized Java object.

Note the following rules for a message of this type:

  • When the message is sent through the REST API, the HTTP request's body is the serialization of a Java object. Any serializable object can be sent through the REST API.

  • When the message is accessed through the Java library, the message is an object of the class javax.jms.ObjectMessage.

  • When the message is received through the REST API, the HTTP response's body is the serialization of the Java object and the Content-Type is as follows:
    application/octet-stream
  • When the message is pushed to a URL by a message push listener, the HTTP request's body is the serialization of the Java object and the Content-Type is as follows:
    application/octet-stream

HTTP

The message's body is a representation of the content of an HTTP request, including the metadata of the content's media type and language.

Note the following rules for a message of this type:

  • When the message is sent through the REST API, the HTTP request's body, Content-Type header, and Content-Language header are used to create an oracle.cloud.messaging.client.HttpContent object.

  • When the message is accessed through the Java library, the message is a javax.jms.ObjectMessage whose content is a populated oracle.cloud.messaging.client.HttpContent object.

  • When the message is received through the REST API, the HTTP response's body, Content-Type header, and Content-Language header are set from the oracle.cloud.messaging.client.HttpContent object.

  • When the message is pushed to a URL by a message push listener, the HTTP request's body, Content-Type header, and Content-Language header are set from the oracle.cloud.messaging.client.HttpContent object.

MAP

The message's body is a set of name/value pairs that defines a mapping from names to values.

Note the following rules for a message of this type:

  • When the message is sent through the REST API, the HTTP request's body is an XML document with the following format:

    <map>
        <entry>
            <name>name</name>
            <type>type</type>
            <value>value</value>
         </entry>
         …
    </map>
    

    The child elements of <map> must all be <entry>. There may be 0 or more <entry> child elements. Every <entry> must contain exactly one <name> element whose content defines the name for the map entry, and either one <type> and one <value> or none of either. If there are multiple <name> elements with the same content, this is an error and the result is unspecified.

    If the <type> and <value> pair is not present, the value assigned to name is null. If the <type> and <value> pair is present, type must be one of the following:

    • boolean: value must be true or false

    • byte: value must be two hexadecimal digits (where a hexadecimal digit is a digit from 0-9 or a letter from A-F)

    • short: value must be a base-10 representation of a Java short integer

    • int: value must be a base-10 representation of a Java int

    • long: value must be a base-10 representation of a Java long integer

    • float: value must be a String representation of a Java float

    • double: value must be a String representation of a Java double

    • string: value must be valid XML character data. An empty <value> object is interpreted as the empty String rather than null.

    • char: value must be a single character

    • bytes: value must be an even-length string of hexadecimal digits (where a hexadecimal digit is a digit from 0-9 or a letter from A-F)

  • When the message is accessed through the Java library, the message is an object of the class javax.jms.MapMessage. Each entry specifies a name/value pair in the javax.jms.MapMessage, with name as name and value as specified by type and value.

  • When the message is received through the REST API, the HTTP response's body is an XML document with the same format as the XML document for the HTTP request's body, and the Content-Type is application/xml.

  • When the message is pushed to a URL by a message push listener, the HTTP request's body is an XML document with the same format as that in an HTTP request to create a MAP message, and the Content-Type is application/xml.

STREAM

The message's body is a sequence of values.

Note the following rules for a message of this type:

  • When the message is sent through the REST API, the HTTP request's body is an XML document with the following format:

    <stream>
        <item>
            <type>type</type>
            <value>value</value>
        </item>
         …
    </stream>
    

    All child elements of <stream> must be <item>. There may be 0 or more <item> child elements. Every <item> must contain either one <type> and one <value> or none of either. If the <type> and <value> pair is not present, the item in the stream is null. If the <type> and <value> pair is present, type and value must match one of the following:

    • boolean: value must be true or false

    • byte: value must be two hexadecimal digits (where a hexadecimal digit is a digit from 0-9 or a letter from A-F)

    • short: value must be a base-10 representation of a Java short integer

    • int: value must be a base-10 representation of a Java int

    • long: value must be a base-10 representation of a Java long integer

    • float: value must be a String representation of a Java float

    • double: value must be a String representation of a Java double

    • string: value must be valid XML character data. Empty <value> elements are interpreted as representing the empty String rather than null.

    • char: value must be a single character

    • bytes: value must be an even-length string of hexadecimal digits (where a hexadecimal digit is a digit from 0-9 or a letter from A-F)

    The values in the stream are in the same order as the <item> elements in the XML document.

  • When the message is accessed through the Java library, the message is an object of the class javax.jms.StreamMessage. Each <item> specifies a value written into the javax.jms.StreamMessage, written in document order.

  • When the message is received through the REST API, the HTTP response's body is an XML document with the same format as the XML document for the HTTP request's body, and the Content-Type is application/xml.

  • When the message is pushed to a URL by a message push listener, the HTTP request's body is an XML document with the same format as that in an HTTP request to create a STREAM message, and the Content-Type is application/xml.

Message Headers and Properties

Message headers and properties are treated as HTTP headers when messages are sent and received through the REST API.

The following table maps message headers to the corresponding HTTP headers:

Message Header HTTP Header

Correlation ID

X-OC-CORRELATION-ID

Delivery Mode

X-OC-DELIVERY-MODE

Destination

X-OC-DESTINATION

Expiration

X-OC-EXPIRATION

Message ID

X-OC-MESSAGE-ID

Redelivered

X-OC-REDELIVERED

Reply To

X-OC-REPLY-TO

Timestamp

X-OC-TIMESTAMP

When a message is sent through the REST API, message properties are set by specifying HTTP headers that follow a specific naming convention. After a message is sent, the properties of the message are treated as standard JMS message properties. When a message is received through the REST API, the message properties are converted to HTTP headers that follow the same naming convention.

Message properties can be set and read through HTTP headers by using the following convention:

X-OC-TYPE-PROPERTY-NAME where NAME and TYPE are strings.

NAME is the message property's name. The name can only contain alphanumeric characters and underscores. All characters are made lowercase by the service.

TYPE is the message property's type, which must be one of the following types:

Message Property Type HTTP Header Value

BOOLEAN

Must be true or false

BYTE

Must be two hexadecimal digits (where a hexadecimal digit is a digit from 0-9 or a letter from A-F)

SHORT

Must be a base-10 representation of a Java short integer

INT

Must be a base-10 representation of a Java int

LONG

Must be a base-10 representation of a Java long integer

FLOAT

Must be a String representation of a Java float

DOUBLE

Must be a String representation of a Java double

STRING

Must be a legal HTTP header value. See Message Headers in the Hypertext Transfer Protocol - HTTP/1.1 document.

XML versus JSON Response Types

While some of the Oracle Messaging Cloud Service REST API endpoints support JSON as a response type, all of the endpoints support XML.

The default response type for all endpoints is XML.

REST API endpoints that only support XML as a response type include:

  • Creating or viewing a message push listener

  • Creating or viewing a durable subscription

  • Receiving a Map or Stream message

  • Creating temporary destinations

  • Listing temporary destinations

  • Retrieving the properties of a single temporary destination

  • Retrieving the properties of a queue browser

The response type for a REST API endpoint can be controlled by setting the HTTP request's Accept header to either application/json or application/xml. To indicate that a client prefers JSON but is willing to accept XML if it is the only format available, the HTTP request's Accept header may be set to, for example, application/json, application/xml;q=0.5.

If an HTTP response from the REST API is the result of receiving a message, the Accept header is ignored. If the HTTP request is a request to receive a message, but an error response is generated, the Accept header is used to determine the format of the error response's body. Otherwise, if the REST API cannot provide a response of the type specified in the Accept header, an HTTP response with status code 406 is returned.