Add real-time capability to your application using Web PubSub and API Management
Tags: azure, websocket, apim, webpubsub
Published: 2022-01-06 08:03:56

Businesses everywhere are looking to extend their operations as a digital platform, creating new channels, finding new customers, and driving deeper engagement with existing ones. Now, with the [API Management (APIM)](https://azure.microsoft.com/services/api-management) and [Web PubSub service (AWPS)](https://azure.microsoft.com/en-us/services/web-pubsub/#overview), you are able to expand the real-time messaging capability of your application with a consistent and modern API gateway.

- Build apps faster and deliver immediate value to your customers through API-first approaches.
- Transform your legacy services into modern REST-based APIs or WebSocket APIs.
- Consistent experience to manage APIs (REST and WebSocket) across clouds and on-premises.

![The overall architecture using Web PubSub and API Management](https://techcommunity.microsoft.com/t5/image/serverpage/image-id/334297i8992406D73FCD7F0/image-size/large?v=v2&px=999)

Let’s go through the key steps together and learn how to implement this reference solution:  

* Create the Azure Web PubSub Service
* Create the Azure API Management service and configure the WebSocket rules
* Update a Web PubSub sample to use the created Azure API Management

## Setup Web PubSub
1. Follow the [steps](https://docs.microsoft.com/azure/azure-web-pubsub/howto-develop-create-instance) to create your Web PubSub service which we refer to as **AWPS1** in the following sections.
2. When created, go to the **Keys** tab for the resource from the Azure portal, and you can see the hostname and connection strings of your resource. There is also a **Client URL Generator tool** in the portal that it can generate some temporarily valid URLs for your WebSocket clients to connect to. Let's use this tool to generate an URL for our demo with a hub called _**demoHub**_. This tool is for quick test purposes only, we also provide APIs in various languages to generate the URL for production usage, for example, [WebPubSubServiceClient.GetClientAccessUri Method for .NET](https://docs.microsoft.com/dotnet/api/azure.messaging.webpubsub.webpubsubserviceclient.getclientaccessuri?view=azure-dotnet).
3. **Copy** the generated **Client Access URL** for later use. Let's have a quick look into the **Client Access URL**, it contains:
    * the hostname of the Web PubSub service _**xxx.webpubsub.azure.com**_ with _**wss**_ scheme,
    * and the path containing the hub name _**/client/hubs/demoHub**_,
    * and a query parameter _**access_token**_ which is the **JWT** token that the Web PubSub service uses to validate and authenticate the WebSocket clients. 
    ![The Keys tab to get the Client Access URL](https://techcommunity.microsoft.com/t5/image/serverpage/image-id/334631i5358313326E447A0/image-size/large?v=v2&px=999)

## Setup API Management
1. Follow the [steps](https://docs.microsoft.com/azure/api-management/get-started-create-service-instance) to create your API Management service which we refer to as **APIM1** in the following sections.
2. When created, go to the **APIs** tab for the resource from the Azure portal, click **Add API** and choose **WebSocket**
    ![Add the WebSocket API](https://techcommunity.microsoft.com/t5/image/serverpage/image-id/334319i04767427E08A4946/image-size/large?v=v2&px=999)
3. Create with the following parameters:
   * **WebSocket URL**: `wss://<your_webpubsub_name>.webpubsub.azure.com/client/hubs/demoHub`
        * Replace `<your_webpubsub_name>` with the name of your **AWPS1**
   * **API URL suffix**: ·client/hubs/demoHub·
        ![Set the WebSocket API](https://techcommunity.microsoft.com/t5/image/serverpage/image-id/334632iBCE9E24FD71813F4/image-size/large?v=v2&px=999)

4. Now you are all set, select the API and use the **Test** tab to test the connection.
    1. Remember the **access_token** query parameter we get from the **AWPS1** Client Access URL? Paste it here as the **access_token** query parameter, and **Connect**.
        ![Test the WebSocket API](https://techcommunity.microsoft.com/t5/image/serverpage/image-id/334635i0C371B28D440C83E/image-size/large?v=v2&px=999)
    2. You can now see in the output **Connected**
         ![Result for the WebSocket API test](https://techcommunity.microsoft.com/t5/image/serverpage/image-id/334636i48FF3DD93018DB82/image-size/large?v=v2&px=999)

## Try samples
Let's update this [publish and subscribe message sample](https://docs.microsoft.com/azure/azure-web-pubsub/tutorial-pub-sub-messages?tabs=csharp) to use **APIM1**, the **only** thing to change is to let [the WebSocket subscriber](https://docs.microsoft.com/azure/azure-web-pubsub/tutorial-pub-sub-messages?tabs=csharp#set-up-the-subscriber) connect to **APIM1** instead.

After the subscriber gets the full URL to connect to **AWPS1**, let's update the **URL** to connect to **APIM**, and don't forget to append the **subscription-key** query parameter if your APIM settings enabled it.

For example, in C#, update the code as below:

```csharp
static async Task Main(string[] args)
{
    // ...

    var serviceClient = new WebPubSubServiceClient(connectionString, hub);
    var url = serviceClient.GetClientAccessUri();

    // Replace the Host with APIM1's, and append APIM1's subscription-key query parameter if it is enabled
    var urlBuilder = new UriBuilder(url);
    // Replace the hostname with APIM's
    urlBuilder.Host = "<APIM1_host_name>.azure-api.net";
    // Get the subscription-key if you enabled it in APIM portal
    var subscriptionKey = "<the_subscription_key>";
    var subscriptionKeyQuery = $"subscription-key={subscriptionKey}";
    urlBuilder.Query = string.IsNullOrEmpty(urlBuilder.Query) ? subscriptionKeyQuery : $"{urlBuilder.Query}&{subscriptionKeyQuery}";
    var apim1Url = urlBuilder.Uri;
    // Start the WebSocket connection
    using (var client = new WebsocketClient(apim1Url))
    {
        // ...
    }
}
```