Access a SharePoint site by server-relative URL with Microsoft Graph

You have a couple options when accessing SharePoint sites with Microsoft Graph, using the site Id and using the server-relative URL. The documentation alludes to the use of the server-relative URL, but it focusses more on the use of the site Id. I want to show you how to use the server-relative URL in this blog post.

Getting a site

The site Id is a unique ID that is a composite of the hostname, the site collection GUID, and the site GUID. It looks something like this:

robwindsortest980.sharepoint.com,130df549-fe92-4160-a4d6-151b48335fa2,427124d7-af02-4009-97f6-5b7c1d17873f

To get this site by the site Id, you would make a GET request to:

https://graph.microsoft.com/v1.0/sites/robwindsortest980.sharepoint.com,5c269f43-747d-4589-93fb-90af4f150b6a,427124d7-af02-4009-97f6-5b7c1d17873f

If you were using the Microsoft Graph SDK for C#, the code would look like this:

var site = await client
    .Sites["robwindsortest980.sharepoint.com,130df549-fe92-4160-a4d6-151b48335fa2,427124d7-af02-4009-97f6-5b7c1d17873f"]
    .Request()
    .GetAsync();

If you have the server-relative URL for a site resource, you can instead use a composite of the hostname and the server-relative URL to the site. It looks something like this:

robwindsortest980.sharepoint.com:/sites/Demo

To get this site by the server-relative URL, you would make a GET request to:

https://graph.microsoft.com/v1.0/sites/robwindsortest980.sharepoint.com:/sites/Demo

If you were using the Microsoft Graph SDK for C#, the code would look like this:

var site = await client
    .Sites["robwindsortest980.sharepoint.com:/sites/Demo"]
    .Request()
    .GetAsync();

But what if you want to get the related resources of a site? For example, what if you want the lists, columns, drives (libraries), or sub-sites? In all cases you can use the site Id to reference the site, in some cases you can use the server-relative URL to reference the site.

To access the Products list from the site used in the examples above, you can use either of these GET requests:

https://graph.microsoft.com/v1.0/sites/robwindsortest980.sharepoint.com,5c269f43-747d-4589-93fb-90af4f150b6a,427124d7-af02-4009-97f6-5b7c1d17873f/lists/Products

https://graph.microsoft.com/v1.0/sites/robwindsortest980.sharepoint.com:/sites/Demo:/lists/Products

If you were using the Microsoft Graph SDK for C#, the code would look like this (note the trailing colon in the server-relative URL in the second example):

var list = await client
    .Sites["robwindsortest980.sharepoint.com,130df549-fe92-4160-a4d6-151b48335fa2,427124d7-af02-4009-97f6-5b7c1d17873f"]
    .Lists["Products"]
    .Request()
    .GetAsync();
var list = await client
    .Sites["robwindsortest980.sharepoint.com:/sites/Demo:"]
    .Lists["Products"]
    .Request()
    .GetAsync();

However, this same calling pattern does not work when trying to get a Drive resource (i.e. a library) related to the site. You have to use both the site Id and the drive Id to access the Drive resource. That is, the first GET request will work but the second and third requests will not:

https://graph.microsoft.com/v1.0/sites/robwindsortest980.sharepoint.com,5c269f43-747d-4589-93fb-90af4f150b6a,427124d7-af02-4009-97f6-5b7c1d17873f/drives/b!Q58mXH10iUWT-5CvTxULatckcUICrwlAl_ZbfB0Xhz_7_TiZ3ZXqTYqonnrCGj1t

https://graph.microsoft.com/v1.0/sites/robwindsortest980.sharepoint.com:/sites/Demo:/drives/Documents

https://graph.microsoft.com/v1.0/sites/robwindsortest980.sharepoint.com:/sites/Demo:/drives/b!Q58mXH10iUWT-5CvTxULatckcUICrwlAl_ZbfB0Xhz_7_TiZ3ZXqTYqonnrCGj1t

Summary

I personally prefer to use the server-relative URL when referencing SharePoint sites because I think it makes code more readable. Just understand that the server-relative URL syntax is not supported in all cases. My strategy is to try using the server-relative URL first and then falling back to use the site when the server-relative URL isn't supported.