Java: Use Microsoft Graph API to access SharePoint sites

ADITYA SHARMA
Xebia Engineering Blog
5 min readOct 20, 2020

In this blog, we will cover the use of Microsoft Graph API to access SharePoint or any other Microsoft cloud resource sites. We will be accessing items stored inside our SharePoint drives so that we can perform some operation on those files (like data entry, downloading to screen, etc).

Before we jump to the implementation lets discuss:

What is Microsoft Graph API?

Microsoft Graph API is a simple, easy to use API that allows access to Microsoft cloud resources such as Office 365, SharePoint, Enterprise Mobility, and Security Services. It provides some REST endpoints that allow access to these services like Office 365.

Currently, there are two versions available: Beta and v1.0. It is recommended to use v1.0 for production, as beta includes some new stuff that may or may not be included in the final versions later on.

For reference, the API documentation can be found at https://docs.microsoft.com/en-us/graph/api/overview?view=graph-rest-1.0

The API endpoint for v1.0 is: https://graph.microsoft.com/v1.0

Let us see the workflow for accessing resources:

In the image we can see that whenever an API or client wants to access the Resource site, we will be having two Objects in between:

Resource Connector: It connects with Authentication Provider to verify token and builds up Microsoft Graph API requests to the Resource Sites using a Graph Client

Authentication Provider: It validates the token, if found correct, it will give access to Resource Site else it will Forbid the request to that site.

Resource site can be any Microsoft Cloud resource.

Now as a 1st step we will build an Authentication Provider and get an Auth Token for that site.

Below are the things required in order to build an authentication provider:

Client ID

Client Secret

Tenant name: example- mytenant.onmicrosoft.com

Now inside our Authentication Provider class we will have two functions:

getAuthToken() : return type String. It gives us the access token.

getAuthProvider() : return type IGraphServiceClient. It gives us the Graph Client which helps us to build and authorize the graph requests.

As a sample, below are the two functions that will help you build your own Authentication Provider. You can use them directly or modify based on your requirement.

public IGraphServiceClient getAuthProvider() {IAuthenticationProvider mAuthenticationProvider;try {String accessToken = getAuthToken();mAuthenticationProvider = request -> request.addHeader("Authorization","Bearer " + accessToken);} catch (Exception e) {throw new Error("Could not create a graph client: " + e.getLocalizedMessage());}return GraphServiceClient.builder().authenticationProvider(mAuthenticationProvider).buildClient();}private String getAuthToken() throws IOException {HttpClient client = HttpClientBuilder.create().build();HttpPost request = new HttpPost(format("https://login.microsoftonline.com/%s/oauth2/v2.0/token", tenant));request.addHeader("Content-Type", "application/x-www-form-urlencoded");request.addHeader("cache-control", "no-cache");List<NameValuePair> nvps = new ArrayList<>();nvps.add(new BasicNameValuePair("client_id", clientId));nvps.add(new BasicNameValuePair("client_secret", clientSecret));nvps.add(new BasicNameValuePair("scope", "https://graph.microsoft.com/.default"));nvps.add(new BasicNameValuePair("grant_type", "client_credentials"));request.setEntity(new UrlEncodedFormEntity(nvps, StandardCharsets.UTF_8));HttpResponse response = client.execute(request);final JsonNode jsonNode = reader.readTree(response.getEntity().getContent());return jsonNode.get("access_token").textValue();}

Once you have created your own Authentication Provider, let's move on to step 2 and build the Resource Connector (SharePoint Connector).

In the Resource Connector we will have a function that will return the InputStream of our File so that we can perform our operations on it.

public InputStream getMyFile(String completePathOfFile) {try {IGraphServiceClient graphClient;graphClient = authProvider.getAuthProvider();JsonElement mainSite = graphClient.customRequest(pathToResourceSite).buildRequest().get();String mainSiteId = mainSite.getAsJsonObject().get("id").getAsString();String siteId = mainSiteId.substring(masterTemplateId.indexOf(",") + 1,masterTemplateId.lastIndexOf(","));InputStream driveItem = graphClient.sites().byId(siteId).drive().root().itemWithPath(completePathOfFile).content().buildRequest().get();return driveItem;} catch (Exception e) {log.error("Error in fetching File" + e.getMessage());throw new RuntimeException("Exception in fetching File");}}

First, let's see what are the completePathOfFile and pathToResourceSite

The completePathOfFile is the path of the file similar to what we have in our PC or Mac like

MainFolder/SubFolder/File.txt

The pathToResourceSite is a graph request having value as per the below format (this is as per the format provided in the graph API documentation):

/sites/{my-site.sharepoint.com}:/sites/{tenant-name}/

Similarly, in order to connect to different tenants within the same my-site.sharepoint.com just change the tenant-name value to the tenant you want to connect to.t

The above function returns InputSteam of our file. Below is the explanation of the code:

⦁ We are building a graphClient which provides us a way to distinguish between valid and invalid requests and return JSON object of our requests.

⦁ We are creating a get request and a JSON of our main site is returned in JsonElement main site.

⦁ From that JSON we are fetching the “id” of our site. This ID is a combination of 3 elements separated by “,”:

hostname: like my-site.sharepoint.com

siteId

webId

⦁ Once we have the Site Id, we can build any request to that site as shown above, inside InputStream driveItem.

Upload Item to Resource Site (SharePoint)

So, we have seen how we can get an Item from our sites. Now let's see how we can upload (post) an item on our sites.

For this, we will create an upload session and access our site using siteId. Then we will provide the item’s path like folder/item.txt and create an upload session.

We also need a chunkedUploadProvider to perform the upload.

Microsoft Graph API also facilitates us with an IProgressCallback<DriveItem> callback, using which we can have a callback for a successful or failed upload of our item.

Below is the code for your reference:

UploadSession uploadSession = graphClient.sites().byId(siteId).drive().root().itemWithPath(path).createUploadSession(new DriveItemUploadableProperties()).buildRequest().post();ChunkedUploadProvider<DriveItem> chunkedUploadProvider =new ChunkedUploadProvider<>(uploadSession, graphClient, myInputStreamFile,getStreamSize(myInputStreamFile), DriveItem.class);// Config parameter is an array of integers// customConfig[0] indicates the max slice size// Max slice size must be a multiple of 320 KiBint[] customConfig = {320 * 1024};// Do the uploadtry {chunkedUploadProvider.upload(callback, customConfig);} catch (IOException e) {log.error("Error in uploading " + e.getMessage());throw new RuntimeException("Exception in uploading");}

Microsoft Graph Explorer

Microsoft has also provided us with a graph explorer to help us build and test our graph APIs. Some samples are also available in the bottom-left corner of the page. Below is the image of graph explorer:

https://developer.microsoft.com/en-us/graph/graph-explorer

Some sample requests are shown below:

To find all sites inside my-tenant site

https://graph.microsoft.com/v1.0/sites

To find a particular site

https://graph.microsoft.com/v1.0/sites/{my-tenant.sharepoint.com}:/sites/{site-name}

To search a file inside a site

https://graph.microsoft.com/v1.0/sites/{siteId}/drive/root/search(q='filename.txt')

To get content of a file

https://graph.microsoft.com/v1.0/sites/{siteId}/drive/root:{path-to-file.txt}:/content

A detailed list/examples of graph requests can be found in the official documentation. You can build or modify this request as per your requirement.

I hope this blog will be useful to all those who are trying to implement similar requirements or studying new concepts. Do let me know in the comments section, what all new things you want to learn and I’ll create an easy to understand blog for you.

--

--