Simulating 429 Throttling in Microsoft Graph API (SharePoint/OneDrive workloads)

Published Aug 20 2021 06:14 AM 1,761 Views

Developing and testing your error handling code is really important to ensure the end product is resilient. I’ve always found this area to be a bit of a minefield when developing against SharePoint and more recently the Microsoft Graph API. I usually resort to using some software that intercepts the calls being made (e.g. Fiddler) and returns a mocked error response. Some error messages (such as a 502 Bad Gateway) are pretty easy to mock, but others are much harder, and must contain certain headers and body content. If you are using some of the SDKs the problem can become even more challenging as they are expecting certain error responses to have particular body structure and content.

 

An addition made to the SharePoint REST API some years ago that I really loved was the ability to “ask” the SharePoint API itself to return a mock 429 (throttling) error. This is brilliant in it’s simplicity, no longer do you need a piece of software intercepting and trying to hand craft valid error responses (especially a tricky one like a 429 with retry-after headers). The way this works with the SharePoint REST API is that you simply add the test429=true URL parameter.

 

 

http://camtoso.sharepoint.com/_api/web/lists?test429=true

 

 

Using this URL would cause SharePoint to respond with a valid 429 error instead of trying to process the request. This lets you easily test your error handling code to ensure your code can handle and retry those 429 when they do crop up in production. Waldek Mastykarz wrote a great post on this behaviour in the SharePoint REST API.

 

Now we’ve all moved to the Microsoft Graph API I assumed this technique wouldn’t work anymore. I recently got curious and tried it anyway, to my surprise it actually does work! Maybe I shouldn’t be that surprised as the Graph API conceptually is passing the calls on to the underlying workload (SharePoint). Now don’t get too excited, it doesn’t work for every call to the Graph API, it will only work for calls that are being passed through to SharePoint so don’t expect to be able to call /teams and use this trick. Using the Microsoft Graph Explorer it was really easy to poke around, here’s some calls that I have tried.

 

SharePoint (/sites)

 

https://graph.microsoft.com/v1.0/sites/root/drives?test429=true

 

 

image

 

SharePoint List Items

 

https://graph.microsoft.com/v1.0/sites/root/lists/{listid}/items?test429=true

 

 

 

OneDrive (/drive)

 

https://graph.microsoft.com/v1.0/me/drive/root/children?test429=true

 

 

image-1

 

 

Look at those beautiful 429 responses that I no longer have to intercept and hand craft. Now what would be amazing is if the Graph API standardised on this and gave us a way via parameters (or headers) to ask the Graph to respond with all the different types of errors that were possible so we could write and test code that was truly resilient and not just “theoretically” resilient until we hit an actual error one day in production and get a response that was a little different to what we were expecting.

1 Comment
Regular Contributor

This an awesome testing feature. Wish it was a standard across other Graph APIs.

%3CLINGO-SUB%20id%3D%22lingo-sub-2668937%22%20slang%3D%22en-US%22%3ESimulating%20429%20Throttling%20in%20Microsoft%20Graph%20API%20(SharePoint%2FOneDrive%20workloads)%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2668937%22%20slang%3D%22en-US%22%3E%3CP%20class%3D%22lia-align-left%22%3EDeveloping%20and%20testing%20your%20error%20handling%20code%20is%20really%20important%20to%20ensure%20the%20end%20product%20is%20resilient.%20I%E2%80%99ve%20always%20found%20this%20area%20to%20be%20a%20bit%20of%20a%20minefield%20when%20developing%20against%20SharePoint%20and%20more%20recently%20the%20Microsoft%20Graph%20API.%20I%20usually%20resort%20to%20using%20some%20software%20that%20intercepts%20the%20calls%20being%20made%20(e.g.%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fcamerondwyer.com%2F2019%2F05%2F16%2Ftop-6-fiddler-tips-for-developers%2F%22%20target%3D%22_blank%22%20rel%3D%22noreferrer%20noopener%20nofollow%22%3EFiddler%3C%2FA%3E)%20and%20returns%20a%20mocked%20error%20response.%20Some%20error%20messages%20(such%20as%20a%20502%20Bad%20Gateway)%20are%20pretty%20easy%20to%20mock%2C%20but%20others%20are%20much%20harder%2C%20and%20must%20contain%20certain%20headers%20and%20body%20content.%20If%20you%20are%20using%20some%20of%20the%20SDKs%20the%20problem%20can%20become%20even%20more%20challenging%20as%20they%20are%20expecting%20certain%20error%20responses%20to%20have%20particular%20body%20structure%20and%20content.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAn%20addition%20made%20to%20the%20SharePoint%20REST%20API%20some%20years%20ago%20that%20I%20really%20loved%20was%20the%20ability%20to%20%E2%80%9Cask%E2%80%9D%20the%20SharePoint%20API%20itself%20to%20return%20a%20mock%20429%20(throttling)%20error.%20This%20is%20brilliant%20in%20it%E2%80%99s%20simplicity%2C%20no%20longer%20do%20you%20need%20a%20piece%20of%20software%20intercepting%20and%20trying%20to%20hand%20craft%20valid%20error%20responses%20(especially%20a%20tricky%20one%20like%20a%20429%20with%20retry-after%20headers).%20The%20way%20this%20works%20with%20the%20SharePoint%20REST%20API%20is%20that%20you%20simply%20add%20the%20test429%3Dtrue%20URL%20parameter.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3Ehttp%3A%2F%2Fcamtoso.sharepoint.com%2F_api%2Fweb%2Flists%3Ftest429%3Dtrue%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EUsing%20this%20URL%20would%20cause%20SharePoint%20to%20respond%20with%20a%20valid%20429%20error%20instead%20of%20trying%20to%20process%20the%20request.%20This%20lets%20you%20easily%20test%20your%20error%20handling%20code%20to%20ensure%20your%20code%20can%20handle%20and%20retry%20those%20429%20when%20they%20do%20crop%20up%20in%20production.%20Waldek%20Mastykarz%20wrote%20a%20great%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fblog.mastykarz.nl%2Fsimulating-throttling-sharepoint%2F%22%20target%3D%22_blank%22%20rel%3D%22noreferrer%20noopener%20nofollow%22%3Epost%20on%20this%20behaviour%20in%20the%20SharePoint%20REST%20API%3C%2FA%3E.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ENow%20we%E2%80%99ve%20all%20moved%20to%20the%20Microsoft%20Graph%20API%26nbsp%3BI%20assumed%20this%20technique%20wouldn%E2%80%99t%20work%20anymore.%20I%20recently%20got%20curious%20and%20tried%20it%20anyway%2C%20to%20my%20surprise%20it%20actually%20does%20work!%20Maybe%20I%20shouldn%E2%80%99t%20be%20that%20surprised%20as%20the%20Graph%20API%20conceptually%20is%20passing%20the%20calls%20on%20to%20the%20underlying%20workload%20(SharePoint).%20Now%20don%E2%80%99t%20get%20too%20excited%2C%20it%20doesn%E2%80%99t%20work%20for%20every%20call%20to%20the%20Graph%20API%2C%20it%20will%20only%20work%20for%20calls%20that%20are%20being%20passed%20through%20to%20SharePoint%20so%20don%E2%80%99t%20expect%20to%20be%20able%20to%20call%20%2Fteams%20and%20use%20this%20trick.%20Using%20the%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fdeveloper.microsoft.com%2Fen-us%2Fgraph%2Fgraph-explorer%2Fpreview%3FWT.mc_id%3DM365-MVP-5002900%22%20target%3D%22_blank%22%20rel%3D%22noreferrer%20noopener%22%3EMicrosoft%20Graph%20Explorer%3C%2FA%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Eit%20was%20really%20easy%20to%20poke%20around%2C%20here%E2%80%99s%20some%20calls%20that%20I%20have%20tried.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ESharePoint%20(%2Fsites)%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3Ehttps%3A%2F%2Fgraph.microsoft.com%2Fv1.0%2Fsites%2Froot%2Fdrives%3Ftest429%3Dtrue%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22image%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F304632i6F55794B753B423B%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22image%22%20alt%3D%22image%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3ESharePoint%20List%20Items%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3Ehttps%3A%2F%2Fgraph.microsoft.com%2Fv1.0%2Fsites%2Froot%2Flists%2F%7Blistid%7D%2Fitems%3Ftest429%3Dtrue%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Fcamerondwyer.files.wordpress.com%2F2021%2F08%2Fimage-2.png%22%20border%3D%220%22%20%2F%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EOneDrive%20(%2Fdrive)%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3Ehttps%3A%2F%2Fgraph.microsoft.com%2Fv1.0%2Fme%2Fdrive%2Froot%2Fchildren%3Ftest429%3Dtrue%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-left%22%20image-alt%3D%22image-1%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F304630iFC7A5A24611E4007%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22image-1%22%20alt%3D%22image-1%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%20class%3D%22lia-align-left%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%20class%3D%22lia-align-left%22%3E%3CSPAN%3ELook%20at%20those%20beautiful%20429%20responses%20that%20I%20no%20longer%20have%20to%20intercept%20and%20hand%20craft.%20Now%20what%20would%20be%20amazing%20is%20if%20the%20Graph%20API%20standardised%20on%20this%20and%20gave%20us%20a%20way%20via%20parameters%20(or%20headers)%20to%20ask%20the%20Graph%20to%20respond%20with%20all%20the%20different%20types%20of%20errors%20that%20were%20possible%20so%20we%20could%20write%20and%20test%20code%20that%20was%20truly%20resilient%20and%20not%20just%20%E2%80%9Ctheoretically%E2%80%9D%20resilient%20until%20we%20hit%20an%20actual%20error%20one%20day%20in%20production%20and%20get%20a%20response%20that%20was%20a%20little%20different%20to%20what%20we%20were%20expecting.%3C%2FSPAN%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-2668937%22%20slang%3D%22en-US%22%3E%3CP%3E%3CSPAN%3EFancy%20that%2C%20a%20very%20handy%20trick%20for%20simulating%20429%20throttling%20in%20SharePoint%20REST%20API%20also%20works%20in%20the%20Microsoft%20Graph%20API%20(SharePoint%2FOneDrive%20workloads).%3C%2FSPAN%3E%3C%2FP%3E%3C%2FLINGO-TEASER%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2669207%22%20slang%3D%22en-US%22%3ERe%3A%20Simulating%20429%20Throttling%20in%20Microsoft%20Graph%20API%20(SharePoint%2FOneDrive%20workloads)%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2669207%22%20slang%3D%22en-US%22%3E%3CP%3EThis%20an%20awesome%20testing%20feature.%20Wish%20it%20was%20a%20standard%20across%20other%20Graph%20APIs.%3C%2FP%3E%3C%2FLINGO-BODY%3E
Co-Authors
Version history
Last update:
‎Aug 20 2021 05:45 AM
Updated by: