4/02/2019

MS Graph: Get DriveItem by File Absolute Url

Microsoft Graph allows to work with OneDrive files and SharePoint documents using DriveItem resource type. Using this entity you can read information about a file, such as size, content, file type, and so on (here is a link to the resource type documentation).
You can get DriveItem object from a specific Drive, Site, Group, or user's connected OneDrive. But for all of these operations you need to know identifiers of parent resources, e.g. drive id, or site id (documentation on how to get drive item).
But what if the file is located in a custom document library, in a subfolder, and on a subsite? And you have only absolute url for the document, like https://your-tenant.sharepoint.com/sites/your-site/your-subsite/DocLibrary/subfolder/file.ext?

If you try to use the approach described in the documentation, you'll need to:
  1. Correctly split the url to have site relative url, document library url, and file path in that library. And the algorithm for that might be really complicated, especially without additional knowledge about site contents.
  2. Get all drives from the site and find drive and its id associated with the document library (unfortunately there is no API to get drive by path like /sites/{site-id}/drives:/path-to-doc-library)
  3. Get driveItem using request like /sites/{your-tenant}:/{site-relative-url}/drives/{drive-id}/root:/{item-path}
All of these look really complicated both from implementation standpoint and number of requests to be done...
But... Good news everyone! And the name of it - MS Graph shares endpoint!
We can actually transform our absolute url into sharing encoded url and use it with /shares endpoint to get driveItem.
So, first, let's encode the url, using the code from official documentation:
string base64Value = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(fileAbsoluteUrl));
string encodedUrl = "u!" + base64Value.TrimEnd('=').Replace('/','_').Replace('+','-');
Note: for JavaScript/TypeScript documentation you can use btoa function.
Now, when we have the sharing url we can get the driveItem:
GET https://graph.microsoft.com/v1.0/shares/{sharing-url}/driveItem
Moreover, if we're working with SharePoint document we can also get related ListItem and all the fields:
GET https://graph.microsoft.com/v1.0/shares/{sharing-url}/driveItem?$expand=listItem($expand=fields)
So, using single request and simple code we can get all the information we need! That's just awesome!

Conclusion

The conclusion here is one sentence: if you need to get drive item by absolute url, use shares endpoint!

That's all for today!
Have fun!

No comments:

Post a Comment