SharePoint
goes Microsoft
Graph
How to use Microsoft Graph
Api to deal with SharePoint
items / files
DIAMOND LEVEL
PLATINUM LEVEL
GOLD LEVEL
THANK YOU TO OUR SPONSORS
/delta approach
Create & Update
Search
Graph vs SP Rest API
Security
considerations
Resources
Agenda
About me
Why something
new?
• Site, List, Item
Getting started
• Expand, select
OData 1
• Filter and deal with different
column types
OData 2
Items vs files
• Markus Moeller
• Microsoft 365 Developer Expert
• Microsoft MVP
• PnP community contributor
• Avanade Germany
• @moeller2_0
• https://mmsharepoint.wordpress.com
• Proud dad of 1 (2yrs)
About me
Why something new?
No matter if low-code or pro-code:
You need an Api to access data ...
• SharePoint → Microsoft 365 development
• SharePoint, Exchange, Teams, Planner, Azure AD …
• V1.0 vs beta endpoint
• Use $whatif to detect underlying product Api
Demo
• How to get your
• Site
• List
• Item
The site as starting point
• Know ID or Url from your runtime context
• Iterate list of /me/followedSites
• Search for sites
• List groups and grab site by relationship ( {groupID} /sites/root )
• Organizations Default Site: /sites/root
The Site-ID
• msharepoint.sharepoint.com, c3bbce0e-14cb-4818-87ba-956d17cf7602,fea4e805-d0bd-4f62-95f3-4b42dd427181
Host (optional) Web-ID (required)
Site-ID (required)
Demo
• What about custom fields?
• $expand
• $orderby
• $select
Demo
• What about filtering?
• $filter
Odata operations
• Projection recommended
• LookupListviewThreshold still a topic …
• $orderby and $expand also reduces # of calls and improves performance
• $filter server-side better than client-side …:
Demo
• Items vs files
ListItem vs DriveItem
ListItem
• $filter on list &$expand=drivItem
DriveItem
• $filter on drive &$expand=listItem
• Projection on custom fields possible
and recommended
Demo
• How to get your
• Item delta
/delta approach
available for other
resources,too
Reliable (better than
webhooks or event
receiver)
Token valid for <=30 days
only
Demo
Create and update
• List items
• Field values
Create and Update
• POST vs PATCH
• Text, Choice, : „text“
• Number: number
• Date: ISOFormat
• Yes/No: true/false
• <Field>LookupID: „LookupId“
➢Use /lists/User Information List/items?$expand=fields to get
UserLookupIDs
Demo
Search
• List items
• Drive items
Graph Search Api
• Runs in user context (delegated permissions)
• Prefer general endpoint https://graph.microsoft.com/v1.0/search/query with entityTypes
• Use KQL, Managed Properties (Refinable!) as you know from SP Rest Api
• Further checkout:
• trimDuplicates
• Search sites, lists, drives only
From DriveItem to ListItem (Search)
"name": "NewFile.txt",
"parentReference": { ...,
"sharepointIds": {
"listId": "cc11f284-f9f5-4441-b74a-e52443d4736d",
"listItemId": "6",
"listItemUniqueId": "214F4A5C-B159-4674-8555-628F189CB73E"
},
"siteId": „<HOST>,c3bbce0e-14cb-4818-87ba-956d17cf7602,fea4e805-d0bd-
4f62-95f3-4b42dd427181"
},
"webUrl": "https://mmsharepoint.sharepoint.com/teams/GraphDemo/Shared
Documents/NewFile.txt"
https://graph.microsoft.com/v1.0/sites/c3bbce0e-14cb-4818-87ba-
956d17cf7602,fea4e805-d0bd-4f62-95f3-4b42dd427181/lists/cc11f284-f9f5-4441-
b74a-e52443d4736d/items/6
Graph vs SP Rest API
Microsoft Graph
• One API fits all
• Modern approach
• One token across M365 app
• Delta approach
• Taxonomy operations
• Expect new things „here“
SP Rest Api
• Very rich operations set
• „Known“ to many SP Devs
• „No auth handling“ in SPFx
• Necessary for Special
operations
Security considerations
• Pefer delegated permissions
• Use SSO wherever possible
• Consider „resource specific consent“ (RSC) when dealing with app
permissions
• Secretless / Managed Identity
Security considerations for SPFx
MSGraphClient
• Uses (shares!) Graph
permissions tenant-wide
• Every app can read/write
sites/user/mail ... !!!
AadHttpClient
• Uses (shares!) access_as_user
permission tenant-wide
• Every app can „call“ your
backend Api (Azure Function ...)
• Your code can secure this
further...
Microsoft Graph = 3rd party access
• Prefer AadHttpClient over MSGraphClient
• Both use „SharePoint Online Client Extensibility“ enterprise application
which grants permission tenant-wide
Resources
• Use Microsoft Graph to query SharePoint items (Presenter's blogpost)
• Query SharePoint items with Microsoft Graph and Search (Presenter's blogpost)
• Use Microsoft Graph to create SharePoint items (Presenter's blogpost)
• Use Microsoft Graph delta approach to increase performance getting SharePoint list
items (Presenter's blogpost)
• Graph Explorer
• API documentation (v1.0)
Questions?
Backlog
Used operations during demo
Site, List, LisItem
• Having https://<YourTeanant>.sharepoint.com/teams/GraphDemo
• We can
https://graph.microsoft.com/v1.0/sites/<YourTeanant>.sharepoint.com:/teams/G
raphDemo
• Now pick the Id and use it in https://graph.microsoft.com/v1.0/sites/{site-id}
• Having the site attach /lists to detect a list we want
• Pick one by https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id} or {list-
title}
• Get the items by attaching /items
• Get specific item by attaching /{item-id}
• https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items/{item-id}
Handling custom fields
• https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-
id}/items/{item-id} has /fields by default
• https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items/
?$expand=fields
• $expand=fields($select=Title,Lastname,Salary) [Projection instead]
• ?$expand=fields&$orderby=fields/Lastname:
• "Field 'Lastname' cannot be referenced in filter or orderby as it is not indexed.
• Add to Header: Prefer HonorNonIndexedQueriesWarningMayFailRandomly
OR
• Index column!!!
$filter items
• Filter text based /items?$expand=fields&$filter=startswith(fields/Title, 'H')
• Filter DateTime /items?$expand=fields&$filter=fields/HireDate lt '2019-01-02’
• Filter Boolean
• $filter=fields/KeyEmployee eq 1
• $filter=fields/KeyEmployee eq 0
• Better: $filter=fields/KeyEmployee ne 1 (Will also show “empty” fields)
• Filter Lookup, Person
/items?$expand=fields&$filter=fields/ManagerLookupId eq 11
ListItem vs DriveItem
• Library as list: /lists/Documents/items
• ?$expand=fields,driveItem
• Switch to Drive:
• Pick parentReference | path from driveItem
• Attach /drives/{drive-ID}/root/children
• ?$expand=listItem($select=id,webUrl;$expand=fields($select=FileLeaf
Ref,Reviewer))
/delta approach
• https://graph.microsoft.com/beta/sites/{site-id}/lists/{list-
id}/items/delta?$expand=fields
• Use "@odata.deltaLink„:
• /items/delta?$expand=fields&token=MzslMjM0OyUyMzE7Mzs1NzkyZjYwMy
1mNThiLTQ0ZDktYjZlMC02YzQzODAwMDE1YWE7NjM4MDExNjA2MTUyMzA
wMDAwOzY5NDE1NjkyODslMjM7JTIzOyUyMzI
• Get new token only:
• &token=latest
Create and update
• POST https://graph.microsoft.com/beta/sites/{site-id}/lists/{list-id}/items
{
"fields": {
"Title": "Pat Pattinson",
"Firstname": "Pat",
"Lastname": "Pattinson",
"Street": "Adelaide Ave«
}
}
• PATCH https://graph.microsoft.com/beta/sites/{site-id}/lists/{list-id}/items/{item-
id}
{
"fields": {
"Street": "Adelaide Avenue",
"StreetNo": 118,
"Salary": 1000.8,
"KeyEmployee": true,
"HireDate": "2022-10-01",
"EmployeeLocationLookupId": "5"
}
}
Search
• POST https://graph.microsoft.com/v1.0/search/query
{ "requests": [
{
"entityTypes": [ "listItem" ],
"query": { "queryString": "*" } ,
"sortProperties": [ { "name": "createdDateTime", "isDescending": "true" } ],
"size": 10,
"from": 10,
"fields": [
"title",
"Author",
"RefinableDecimal09",
"KeyEmployeeOWSBOOL",
"LastModifiedTime"
]
}
]}
Bonus: Search aggregations
"aggregations": [
{
"field": "lastModifiedTime", // Refinable!!!
"size": 3,
"bucketDefinition": {
"sortBy": "keyAsString",
"isDescending": "false",
"minimumCount": 0,
"ranges": [
{
"to": "2022-07-31T23:59:59Z"
},
{
"from": "2022-07-31T23:59:59Z",
"to": "2022-08-31T23:59:59Z"
},
{
"from": "2022-08-31T23:59:59Z"
}
]
}
}
]
Refine:
"aggregationFilters": [
" lastModifiedTime:range(2022-08-31T23:59:59.0000000Z, max,
to="le")" // Take <aggregationFilterToken> from prev result
]

SharePoint goes Microsoft Graph

  • 1.
    SharePoint goes Microsoft Graph How touse Microsoft Graph Api to deal with SharePoint items / files
  • 2.
    DIAMOND LEVEL PLATINUM LEVEL GOLDLEVEL THANK YOU TO OUR SPONSORS
  • 3.
    /delta approach Create &Update Search Graph vs SP Rest API Security considerations Resources Agenda About me Why something new? • Site, List, Item Getting started • Expand, select OData 1 • Filter and deal with different column types OData 2 Items vs files
  • 4.
    • Markus Moeller •Microsoft 365 Developer Expert • Microsoft MVP • PnP community contributor • Avanade Germany • @moeller2_0 • https://mmsharepoint.wordpress.com • Proud dad of 1 (2yrs) About me
  • 5.
    Why something new? Nomatter if low-code or pro-code: You need an Api to access data ... • SharePoint → Microsoft 365 development • SharePoint, Exchange, Teams, Planner, Azure AD … • V1.0 vs beta endpoint • Use $whatif to detect underlying product Api
  • 6.
    Demo • How toget your • Site • List • Item
  • 7.
    The site asstarting point • Know ID or Url from your runtime context • Iterate list of /me/followedSites • Search for sites • List groups and grab site by relationship ( {groupID} /sites/root ) • Organizations Default Site: /sites/root
  • 8.
    The Site-ID • msharepoint.sharepoint.com,c3bbce0e-14cb-4818-87ba-956d17cf7602,fea4e805-d0bd-4f62-95f3-4b42dd427181 Host (optional) Web-ID (required) Site-ID (required)
  • 9.
    Demo • What aboutcustom fields? • $expand • $orderby • $select
  • 10.
    Demo • What aboutfiltering? • $filter
  • 11.
    Odata operations • Projectionrecommended • LookupListviewThreshold still a topic … • $orderby and $expand also reduces # of calls and improves performance • $filter server-side better than client-side …:
  • 12.
  • 13.
    ListItem vs DriveItem ListItem •$filter on list &$expand=drivItem DriveItem • $filter on drive &$expand=listItem • Projection on custom fields possible and recommended
  • 14.
    Demo • How toget your • Item delta
  • 15.
    /delta approach available forother resources,too Reliable (better than webhooks or event receiver) Token valid for <=30 days only
  • 16.
    Demo Create and update •List items • Field values
  • 17.
    Create and Update •POST vs PATCH • Text, Choice, : „text“ • Number: number • Date: ISOFormat • Yes/No: true/false • <Field>LookupID: „LookupId“ ➢Use /lists/User Information List/items?$expand=fields to get UserLookupIDs
  • 18.
  • 19.
    Graph Search Api •Runs in user context (delegated permissions) • Prefer general endpoint https://graph.microsoft.com/v1.0/search/query with entityTypes • Use KQL, Managed Properties (Refinable!) as you know from SP Rest Api • Further checkout: • trimDuplicates • Search sites, lists, drives only
  • 20.
    From DriveItem toListItem (Search) "name": "NewFile.txt", "parentReference": { ..., "sharepointIds": { "listId": "cc11f284-f9f5-4441-b74a-e52443d4736d", "listItemId": "6", "listItemUniqueId": "214F4A5C-B159-4674-8555-628F189CB73E" }, "siteId": „<HOST>,c3bbce0e-14cb-4818-87ba-956d17cf7602,fea4e805-d0bd- 4f62-95f3-4b42dd427181" }, "webUrl": "https://mmsharepoint.sharepoint.com/teams/GraphDemo/Shared Documents/NewFile.txt" https://graph.microsoft.com/v1.0/sites/c3bbce0e-14cb-4818-87ba- 956d17cf7602,fea4e805-d0bd-4f62-95f3-4b42dd427181/lists/cc11f284-f9f5-4441- b74a-e52443d4736d/items/6
  • 21.
    Graph vs SPRest API Microsoft Graph • One API fits all • Modern approach • One token across M365 app • Delta approach • Taxonomy operations • Expect new things „here“ SP Rest Api • Very rich operations set • „Known“ to many SP Devs • „No auth handling“ in SPFx • Necessary for Special operations
  • 22.
    Security considerations • Peferdelegated permissions • Use SSO wherever possible • Consider „resource specific consent“ (RSC) when dealing with app permissions • Secretless / Managed Identity
  • 23.
    Security considerations forSPFx MSGraphClient • Uses (shares!) Graph permissions tenant-wide • Every app can read/write sites/user/mail ... !!! AadHttpClient • Uses (shares!) access_as_user permission tenant-wide • Every app can „call“ your backend Api (Azure Function ...) • Your code can secure this further... Microsoft Graph = 3rd party access • Prefer AadHttpClient over MSGraphClient • Both use „SharePoint Online Client Extensibility“ enterprise application which grants permission tenant-wide
  • 24.
    Resources • Use MicrosoftGraph to query SharePoint items (Presenter's blogpost) • Query SharePoint items with Microsoft Graph and Search (Presenter's blogpost) • Use Microsoft Graph to create SharePoint items (Presenter's blogpost) • Use Microsoft Graph delta approach to increase performance getting SharePoint list items (Presenter's blogpost) • Graph Explorer • API documentation (v1.0)
  • 25.
  • 26.
  • 27.
    Site, List, LisItem •Having https://<YourTeanant>.sharepoint.com/teams/GraphDemo • We can https://graph.microsoft.com/v1.0/sites/<YourTeanant>.sharepoint.com:/teams/G raphDemo • Now pick the Id and use it in https://graph.microsoft.com/v1.0/sites/{site-id} • Having the site attach /lists to detect a list we want • Pick one by https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id} or {list- title} • Get the items by attaching /items • Get specific item by attaching /{item-id} • https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items/{item-id}
  • 28.
    Handling custom fields •https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list- id}/items/{item-id} has /fields by default • https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items/ ?$expand=fields • $expand=fields($select=Title,Lastname,Salary) [Projection instead] • ?$expand=fields&$orderby=fields/Lastname: • "Field 'Lastname' cannot be referenced in filter or orderby as it is not indexed. • Add to Header: Prefer HonorNonIndexedQueriesWarningMayFailRandomly OR • Index column!!!
  • 29.
    $filter items • Filtertext based /items?$expand=fields&$filter=startswith(fields/Title, 'H') • Filter DateTime /items?$expand=fields&$filter=fields/HireDate lt '2019-01-02’ • Filter Boolean • $filter=fields/KeyEmployee eq 1 • $filter=fields/KeyEmployee eq 0 • Better: $filter=fields/KeyEmployee ne 1 (Will also show “empty” fields) • Filter Lookup, Person /items?$expand=fields&$filter=fields/ManagerLookupId eq 11
  • 30.
    ListItem vs DriveItem •Library as list: /lists/Documents/items • ?$expand=fields,driveItem • Switch to Drive: • Pick parentReference | path from driveItem • Attach /drives/{drive-ID}/root/children • ?$expand=listItem($select=id,webUrl;$expand=fields($select=FileLeaf Ref,Reviewer))
  • 31.
    /delta approach • https://graph.microsoft.com/beta/sites/{site-id}/lists/{list- id}/items/delta?$expand=fields •Use "@odata.deltaLink„: • /items/delta?$expand=fields&token=MzslMjM0OyUyMzE7Mzs1NzkyZjYwMy 1mNThiLTQ0ZDktYjZlMC02YzQzODAwMDE1YWE7NjM4MDExNjA2MTUyMzA wMDAwOzY5NDE1NjkyODslMjM7JTIzOyUyMzI • Get new token only: • &token=latest
  • 32.
    Create and update •POST https://graph.microsoft.com/beta/sites/{site-id}/lists/{list-id}/items { "fields": { "Title": "Pat Pattinson", "Firstname": "Pat", "Lastname": "Pattinson", "Street": "Adelaide Ave« } } • PATCH https://graph.microsoft.com/beta/sites/{site-id}/lists/{list-id}/items/{item- id} { "fields": { "Street": "Adelaide Avenue", "StreetNo": 118, "Salary": 1000.8, "KeyEmployee": true, "HireDate": "2022-10-01", "EmployeeLocationLookupId": "5" } }
  • 33.
    Search • POST https://graph.microsoft.com/v1.0/search/query {"requests": [ { "entityTypes": [ "listItem" ], "query": { "queryString": "*" } , "sortProperties": [ { "name": "createdDateTime", "isDescending": "true" } ], "size": 10, "from": 10, "fields": [ "title", "Author", "RefinableDecimal09", "KeyEmployeeOWSBOOL", "LastModifiedTime" ] } ]}
  • 34.
    Bonus: Search aggregations "aggregations":[ { "field": "lastModifiedTime", // Refinable!!! "size": 3, "bucketDefinition": { "sortBy": "keyAsString", "isDescending": "false", "minimumCount": 0, "ranges": [ { "to": "2022-07-31T23:59:59Z" }, { "from": "2022-07-31T23:59:59Z", "to": "2022-08-31T23:59:59Z" }, { "from": "2022-08-31T23:59:59Z" } ] } } ] Refine: "aggregationFilters": [ " lastModifiedTime:range(2022-08-31T23:59:59.0000000Z, max, to="le")" // Take <aggregationFilterToken> from prev result ]