Technical Articles
Consuming Microsoft 365 API in the Cloud Application Programming (CAP) Model
The SAP Devtoberfest 2020 challenge brought new insights to simplify the consuming external API in NodeJS and the Cloud Application Programming (CAP) Model and combine them with a concept for integrating Microsoft Azure and Google Cloud APIs.
As a result of this challenge, the SAP mentor’s community announced a new node.js library CDS-SCP-API for simplifying the consuming external service in Cloud Application Programming (CAP) Model. This blog will explain how you can use this node.js library for consuming Microsoft 365 APIs.
We will use the Microsoft Graph API for reading all users’ full profiles, which API documentation can be found at Microsoft Graph REST API v1.0 documentation. But you can use any API which is available at Microsoft Azure.
To use Microsoft 365 APIs, we first need to configure the Microsoft Graph API layer in Microsoft Azure. These 19 configuration steps in Microsoft Azure are written here in the documentation of the node.js library CDS-SCP-API.
After we have configured Microsoft Azure, we need to configure our destination in the SAP Cloud Platform Destination Service.
URL : https://graph.microsoft.com
Client ID : <Application client ID of Azure App>
Client Secret : <Clients Secrets Value of Azure App>
Token Service URL : https://login.microsoftonline.com/<Directory Tenant ID of Azure App>/oauth2/v2.0/token
or <Token Service URL : <Application OAuth 2.0 token Endpoint(v2) of Azure App>
Scope : https://graph.microsoft.com/.default
Now we set up SAP Cloud Platform and Microsoft Azure, we are ready to build our CAP project.
- Create a new folder and enter the new folder
mkdir <cds-azure-example-folder> cd <cds-azure-example-folder>
- Initialize as CAP CDS project
cds init
- Add cds-scp-API dependencies in the package.json file.
"dependencies": { ... "@sapmentors/cds-scp-api": "latest" },
- install the node packages by running
npm install
- add a file named msgraph-user-service.cds with the following cds definition in the srv folder
@impl:'msgraph-user-service.js' @cds.query.limit: 100 service MSGraphService @(requires:'any'){ @cds.persistence.skip entity User { key aad_id : String; username : String; displayName : String; givenName : String; surname : String; isAzureActiveDirectory : Boolean; } }
- add a file named msgraph-user-service.js with the following cds definition in the srv folder
const cdsapi = require("@sapmentors/cds-scp-api"); const readFunction = async (req) => { let destination = 'MSGraph' const url = `/v1.0/users/` const service = await cdsapi.connect.to(destination); const graphUser = await service.run({ url: url }) let users = graphUser.value.map(graph_user => { var user = {} user.aad_id = graph_user.id user.username = graph_user.userPrincipalName user.displayName = graph_user.displayName user.givenName = graph_user.givenName user.surname = graph_user.surname user.isAzureActiveDirectory = true return user }) return users } module.exports = (srv) => { srv.on('READ', 'User', readFunction) }
- create a default-env.json file as described in the prerequisites for running examples locally
- Start CDS watch to start the application.
cds watch
- Open http://localhost:4004 in your browser to open an overview of the CAP services.
- Click on the link User to see the data from Microsoft Azure Active Directory User List API.
This is something that was on my todo list (i.e getting user details from O365) so thank you for sharing this!
Robert Eijpe > I followed your instructions but when I run cds watch I get the following error:
Note: I also had to install the module directly from GitHub as it’s not published on npm:
EDIT: I found the issue -> I just needed to remove the following line of code (not necessary anyway):
Dear Robert Eijpe ,
Thanks for the nice blog and the npm package.
I tried following the same steps, but upon execution I am getting below error -
Could you please guide on what I might be missing upon?
Best Regards,
Shyam Vasani
Hi Shyam,
I am also facing the same issue.. Did you got any resolution for the above error.
Thanks,
Mary Silvester
Hi,
Thanks for posting this very interesting blog.
I have a question regarding point 7. - where can I find the prerequisites in which the creation of a default-env.json file is described?
Many thanks in advance,
Krzysztof
See https://github.com/saphanaacademy/DefaultEnv
Hi Robert,
I have an issue with the $search parameter when I try to read data of a particular user.
I build the url as follows:
const url = `/users/?$search="onPremisesSamAccountName:ABCDE"`
But then I get the error which says:
"Request with $search query parameter only works through MSGraph with a special request header: 'ConsistencyLevel: eventual'"
I have added the property URL.headers.ConsistencyLevel to destination properties in SAP BTP, but it does not work.
I have also tried to set this header property explicitly:
const graphUser = await service.run({
url: url,
headers: { "ConsistencyLevel": "Eventual"}
})
But in both cases I get the same error message.
Do you know how to request the data of a particular user from Graph or how to correctly set ConsistencyLevel property in request header?