What is this about?
This was a brief introduction to Microsoft GraphAPI for interested colleagues at work. Just a quick look at how to get started quickly, what you need to know to move on, and where to find out more information.
A Quick API History
- SOAP. Many of us old coders still have the scars from dealing with SOAP. At least initially a pure XML1 communication method, you had a single URL you called with a POST and complex body. Usefully, that endpoint could also describe itself as long as you could read XML. You would then use that to try and figure out how to talk to the functions contained within and their parameter types, which was not fun.
- POST an XML file containing the function being called as well as its parameters.
- REST. This moved from a single URL to call to having individual URLs dedicated to their own set of functions. It was easier to understand for the coder, but the API no longer described itself, so you needed to have separate documentation. Or guess. Instead of only having POSTed content, it could use many more methods to talk to it.
- Methods + URL/BODY calling functions with parameters
- GraphAPI (you are here). It's REST but more so -- it has additional standardised query parameters to tweak what the functions do.
- Methods + URL/BODY calling functions with function parameters and additional function control parameters.
- Don’t confuse GraphAPI with GraphQL2. This expects you to understand the data structure at the server end and construct POST content (JSON) that has the query and fields you want to do things to.
- POST a JSON file that holds the action being performed, including the fields/ joins/ etc.
What can it do?
CRUD! That's "Create, Read, Update, and Delete" things in the Microsoft 365 environment. So you can use it to read mail, update your status, delete planner tasks people assign to you (yay!), and those same people can recreate them (boo!)
In doing this, it can act as You (as in the person who has logged in to GraphAPI, known as "delegated"), or as Friend Computer (for unattended, repeated service tasks and the like, known as "application").
Here's a quick screengrab from the manual of a bunch of things it can do:
OK, this is how I break down the sections of talking to the Graph API:
OAuth is how you log into GraphAPI using your normal Microsoft credentials. It's a standard, which is nice. This is how delegated access works:
- prompt the user to log in;
- the user logs in;
- they use their access to do-the-thing.
That way they can only do what they already have access to do. Safety! As part of OAuth you also further restrict what they can do - so just because they log into your Email app, they shouldn't start assigning jobs to everyone.
Permissions are spoken about a bit later.
access token is sent with every request, authorising Microsoft Graph to act on the logged-in person's behalf, or as the service robot that's logged in.
access token has a limited life span to ensure the app can't act as the person forever. Once the token expires the user will have to log in again - unless you have added the scope of
offline_access. This will give you a
refresh token to go with your access token - once the access token expires you can use the refresh token to get a new one - at least until you revoke the refresh token or you change your password.
Since an application using Application credentials doesn't act as a person, it doesn't need to send a user to login to get their credentials - but it still does the swapsies with Microsoft's OAuth endpoint to get the
Methods are part of the web standard. When you read a webpage like Google, your browser sends a "GET" to ... get ... the content. When you fill in a form, typically the browser "POST"s that content to the server. So it tells the back end server what you're doing. GET and POST have friends:
|Method||Does what||Post body|
|POST||Create||Full content of the new Thing|
|PUT||Create or update||Full content of the Thing. Update if the Thing already exists, otherwise create|
|PATCH||Update||Key field and any updated fields. Does not need the full record|
|DELETE||Delete||Can have the key in the URL or the Post body.|
REST, and Microsoft GraphAPI, use the methods to figure out the action we're doing. Sent a GET request? We're after information, no changes. Sent a PATCH? Well, if the key doesn't match send an error - don't try and create it.
3. Request (URL + Body)
Then there's the URL itself. Breaking it down (note the Method specified before the URL)
The URL starts with the protocol of
https - gotta be secure. Next, we have
graph.microsoft.com - this is where all the graph queries are sent, the webserver address itself.
v1.0 is the version - Microsoft is being a good citizen and versioning the API visibly in the URL. Then the path, in the example
/subscriptions - this tells the server what function we're trying to run.
Some functions have an extra somethin' somethin'. We can add extra commands to control what happens when the command is run. For example, in this example,
$select=id tells the request to only return the
id of the
result, not the entire object. Good if that's all you'll be processing.
For commands that change things, you need to send what you're changing. You put that in the body - in the example that big JSON snippet is what I'm telling Microsoft Graph to use in the
/subscriptions create action.
At this time in the presentation, I opened up GraphAPI Explorer and the Microsoft GraphAPI documentation and had some guided play. You should too. Log in or browse as a guest. The left pane has a bunch of example queries you can try to see the results, you can also edit the URL, body, method etc. to try any other queries.
Note if you have permission denied, there's a permissions tab that can let you alter some permissions you can run - but not all!
The GraphAPI explorer is great for running one-off queries for yourself to find things. Like, look up your profile, using search, or others. But if you want to make it into a real application you'll need to register it. The Application Registration interface in the Azure Portal is where you need to go. Clicking on the new registration you give it enough details that future you can know just what the hell you were thinking and create your app. I broke down some vital things to know in this process:
- Copy down the Application (client) ID - you need that in your OAuth code
- Copy down the Directory (tenant) ID - you need that in your OAuth code too
- Authentication - this is part of OAuth, included in your OAuth code, but also a configuration that you choose. This is where Microsoft sends your users to after they log in to tell your app "Yup, they're cool, here's their ID card receipt, swap that with security for their ID"
- Certificates and secrets - you need this in your OAuth code also. Either way you choose to authenticate, protect these as if they were passwords. Never commit them in code.
- API permissions - now here is where you tell Microsoft Graph (and your administrators) just what your app allows the user to do. There's a good explanation for each permission if you hover over the (i) icon in the permission explorer. You fill your shopping cart with the minimum security level of permissions required to do what you need to do for the user. Note that every permission you ask for will be shown to the user when they log in the first time - so the user can authorise your app with full knowledge of what it could do.
- Note that some permissions are Super Scary - like the ability to edit any group. These require a tenancy Admin to step in and authorise your app to do this. It can feel odd - for example, I can't edit my group memberships without having access to edit all groups. Them's the breaks.
I ended with some tips I've gathered from playing with GraphAPI:
- Always check for a pagination
@odata.nextLinkto ensure you’ve got all the entries
- The main page of your app registration has our Tenancy ID in it, as well as Application/ Client ID. Once generated, you can’t get your secret back though - use a password manager!
- The default scope is your friend. Rather than having to specify the specific permissions in your app in the OAuth
scopeparameter, you can just use
https://graph.microsoft.com/.defaultand it gets all the ones you assigned. One config change to rule them all.
- Graph API has some other cool things like Subscriptions (where MicrosoftGraphAPI will call an endpoint you specify when something you're subscribed to happens on its end (like a new email, or teams status change)) and Search (you can specify a term and search all the SharePoint lists or OneDrive folders you have access to).
Just like a web page, always end giving people something else to do rather than being a dead end. I put up links to Postman and Insomnia as my REST clients of choice and gave a walkthrough of how
to set Insomnia up with GraphAPI. I also noted that Insomnia lets you chain requests together - do a
GET in one, parse the result, and use it in the next
POST call. It's very neat.
So that was the summary of the presentation. Was there anything I should've covered? We had minutes at the end to go through a few specific problems some of the more experienced people had brought, but we all agreed to meet again in a fortnight once people had had a chance to play so we could do some more targeted learning.
I think it went well. There was good feedback at least.