A datasource for Microsoft Graph API to access Microsoft 365 services including Azure AD, Outlook, OneDrive, SharePoint, and more.
interface MicrosoftGraphConfig extends DatasourceConfig {
tenantId: string; // Azure AD tenant ID
clientId: string; // Application client ID
clientSecret: string; // Application client secret
scopes?: string[]; // OAuth scopes (defaults to ['.default'])
}import { DatasourceCatalog } from '@statuscompliance/databinder';
import { MicrosoftGraphDatasource } from '@statuscompliance/databinder/datasources';
const catalog = new DatasourceCatalog();
catalog.registerDatasource(MicrosoftGraphDatasource);
const graphApi = catalog.createDatasourceInstance('microsoft-graph', {
tenantId: 'your-tenant-id',
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
scopes: ['https://graph.microsoft.com/.default']
}, 'graph-instance');
const linker = new Linker({ datasources: [graphApi] });
const dataBinder = new DataBinder({ linker });Lists items in a SharePoint site folder.
const items = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'listSiteItems',
siteId: 'contoso.sharepoint.com,site-guid,web-guid',
folderPath: 'Documents/Reports'
});Gets a SharePoint site ID by its path.
const site = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'getSiteIdByPath',
sitePath: 'contoso.sharepoint.com:/sites/TeamSite'
});
console.log('Site ID:', site.data.id);// List all users (requires User.Read.All permission)
const users = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
endpoint: '/users',
query: {
filters: {
$filter: "startswith(displayName,'John')",
$select: 'id,displayName,mail,userPrincipalName'
}
}
});
// Get specific user
const user = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
endpoint: '/users/user@domain.com'
});
// Get user's manager
const manager = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
endpoint: '/users/user@domain.com/manager'
});// List all groups
const groups = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
endpoint: '/groups',
query: {
filters: {
$filter: "groupTypes/any(c:c eq 'Unified')", // Office 365 groups
$select: 'id,displayName,description'
}
}
});
// Get group members
const members = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
endpoint: '/groups/{group-id}/members'
});// List messages from inbox
const messages = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
endpoint: '/users/user@domain.com/messages',
query: {
filters: {
$filter: "isRead eq false",
$select: 'subject,from,receivedDateTime',
$orderby: 'receivedDateTime desc',
$top: 50
}
}
});
// Send an email
await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
method: 'POST',
endpoint: '/users/user@domain.com/sendMail',
body: {
message: {
subject: 'Hello from DataBinder',
body: {
contentType: 'HTML',
content: '<h1>Hello</h1><p>This is a test email.</p>'
},
toRecipients: [
{
emailAddress: {
address: 'recipient@domain.com'
}
}
]
}
}
});// List files in OneDrive
const files = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
endpoint: '/users/user@domain.com/drive/root/children'
});
// Upload a file
await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
method: 'PUT',
endpoint: '/users/user@domain.com/drive/root:/Documents/test.txt:/content',
body: 'File content here',
headers: {
'Content-Type': 'text/plain'
}
});
// Download a file
const fileContent = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
endpoint: '/users/user@domain.com/drive/items/{item-id}/content'
});// Get site by path
const site = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'getSiteIdByPath',
sitePath: 'contoso.sharepoint.com:/sites/TeamSite'
});
// List document libraries
const libraries = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
endpoint: `/sites/${site.data.id}/drives`
});
// List files in a folder
const files = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'listSiteItems',
siteId: site.data.id,
folderPath: 'Shared Documents'
});- Register an app in Azure Portal
- Go to Azure Active Directory > App registrations
- Create a new registration
- Note the Application (client) ID and Directory (tenant) ID
- Create a Client secret under Certificates & secrets
Configure API permissions in your app registration:
Delegated permissions (user context):
User.Read- Read user profileMail.Read- Read user mailFiles.Read.All- Read all filesSites.Read.All- Read items in all site collections
Application permissions (app-only context):
User.Read.All- Read all usersGroup.Read.All- Read all groupsMail.Read- Read mail in all mailboxesSites.Read.All- Read all site collections
Microsoft Graph supports OData query parameters:
const users = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
endpoint: '/users',
query: {
filters: {
$filter: "startswith(displayName,'A')",
$select: 'id,displayName,mail',
$orderby: 'displayName',
$top: 100,
$skip: 0
}
}
});Common OData parameters:
$filter- Filter results$select- Select specific properties$orderby- Sort results$top- Limit number of results$skip- Skip number of results$expand- Expand related entities$count- Include count of results
Microsoft Graph uses @odata.nextLink for pagination:
let allUsers = [];
let endpoint = '/users';
while (endpoint) {
const response = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
endpoint,
responseOptions: { fullResponse: true }
});
allUsers.push(...response.data.value);
endpoint = response.data['@odata.nextLink']
? response.data['@odata.nextLink'].replace('https://graph.microsoft.com/v1.0', '')
: null;
}Execute multiple requests in a single call:
const batchResponse = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
method: 'POST',
endpoint: '/$batch',
body: {
requests: [
{
id: '1',
method: 'GET',
url: '/users/user1@domain.com'
},
{
id: '2',
method: 'GET',
url: '/users/user2@domain.com'
}
]
}
});try {
const user = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
endpoint: '/users/nonexistent@domain.com'
});
} catch (error) {
if (error instanceof NotFoundError) {
console.log('User not found');
} else if (error instanceof AuthenticationError) {
console.log('Authentication failed - check credentials and permissions');
}
}Microsoft Graph implements throttling:
- Most requests: 2,000 requests per second per tenant
- Per user: 120 requests per second
The datasource includes automatic retry with exponential backoff for throttled requests.
- Use service principals for automated scenarios
- Request minimal permissions (principle of least privilege)
- Use $select to request only needed properties
- Implement pagination for large result sets
- Use batch requests to reduce network calls
- Cache responses when appropriate
- Handle throttling with retry logic
- Monitor token expiration (tokens expire after 1 hour)
const events = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
endpoint: '/users/user@domain.com/calendar/events',
query: {
filters: {
$filter: "start/dateTime ge '2024-01-01T00:00:00Z'",
$select: 'subject,start,end,attendees',
$orderby: 'start/dateTime'
}
}
});const team = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
method: 'POST',
endpoint: '/teams',
body: {
'template@odata.bind': "https://graph.microsoft.com/v1.0/teamsTemplates('standard')",
displayName: 'My New Team',
description: 'Team description',
members: [
{
'@odata.type': '#microsoft.graph.aadUserConversationMember',
roles: ['owner'],
'user@odata.bind': "https://graph.microsoft.com/v1.0/users('user-id')"
}
]
}
});const searchResults = await dataBinder.fetchFromDatasource('graph-instance', {
methodName: 'default',
endpoint: '/search/query',
method: 'POST',
body: {
requests: [
{
entityTypes: ['driveItem'],
query: {
queryString: 'budget report'
}
}
]
}
});For more details on Microsoft Graph API: