EWS streaming notifications in Microsoft Graph: what replaces them

EWS has three kinds of notifications: pull, push and streaming. Microsoft Graph has change notifications delivered to an endpoint, and delta queries. A long-lived connection like StreamingSubscriptionConnection is not among them.

How the three EWS models map

EWSMicrosoft GraphWhat changes
Pull: Subscribe, then GetEvents on a timerDelta query on the folderThe answer is the items that changed; there are no event types
Push: Exchange calls your web serviceSubscription with a webhookNeeds an HTTPS endpoint Microsoft can reach; subscriptions expire and have to be renewed
Streaming: StreamingSubscriptionConnectionNo counterpartChoose a webhook or a delta query on a timer

Microsoft’s mapping page sends applications that use pull notifications to the delta query for messages, and maps push notifications to subscriptions. Streaming is not in the table. Microsoft’s article on migrating notifications says that Graph has no equivalent of the streaming model and that applications built on it usually need a redesign.

Option 1: a subscription with a webhook

The application creates a subscription for a resource, for example the messages of one mailbox folder, and Microsoft posts a notification to its HTTPS endpoint when something changes.

  • The endpoint has to be reachable from Microsoft and has to answer a validation request when the subscription is created. A service behind a firewall that only makes outbound calls, which is where streaming notifications were popular, cannot receive webhooks directly. Graph can also deliver to Azure Event Hubs or Azure Event Grid, which the application then reads with an outbound connection.
  • A subscription for messages, events or contacts lasts at most 10,080 minutes, a little under seven days, and has to be renewed before that. With resource data included in the notification the limit is 1,440 minutes.
  • Microsoft documents an average delay under one minute and a maximum of three minutes for message notifications.
  • Notifications can be lost. Graph sends lifecycle notifications when a subscription is removed or notifications were missed, and the answer to both is a delta query.

Option 2: a delta query on a timer

The application asks each folder for what changed since the last call and stores the delta link from the answer. Nothing has to be reachable from outside, and nothing expires within a week. The delay is the timer interval.

For calendars, Graph v1.0 documents delta only on a calendar view between two dates. A subscription on events, followed by a read of the event, covers changes outside such a window.

Events do not match one to one

EWS reports what happened: NewMail, Created, Modified, Moved, Copied, Deleted, FreeBusyChanged. Graph reports the kind of change: created, updated, deleted. A delta query reports no events at all, only the items as they are now.

  • A move arrives as a deletion in one folder and a creation in the other, with a different ID unless you use immutable IDs.
  • A copy is a creation. To tell it from a new message you compare something stable, such as the Internet message ID.
  • An item that was created and deleted between two delta calls produces nothing.
  • A hard delete is a deletion. EWS reported it as a move to Recoverable Items.
  • Expect more updated notifications than EWS sent Modified events, because one action often changes an item several times. Collect notifications for a few seconds, then read the item or run the delta query once.

Watermarks

An EWS subscription could be resumed from a watermark. Neither Graph mechanism takes one. After the switch the application subscribes again and catches up with one full synchronization, then keeps the delta links.

What Sunsetless EWS does

Sunsetless EWS keeps Subscribe, GetEvents, StreamingSubscriptionConnection and push subscriptions working. Underneath it runs delta queries on a timer, every 10 seconds by default, and turns the differences into EWS events. The subscriptions live in the application’s process and need no endpoint. Because the events come from comparing states, they are net changes: the compatibility table lists exactly where that differs from Exchange.

Sources

More guides