Skip to content

Graph Lite simplifies the Microsoft Graph API by slicing the monolith into multiple Graph Lite APIs and importing these Graph Lite APIs automatically into Azure API Management.

License

Notifications You must be signed in to change notification settings

erwinkramer/msgraph-lite

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Graph Lite

CC BY-NC-SA 4.0 GitHub commit activity

Graph Lite simplifies the Microsoft Graph API by slicing the monolith into multiple Graph Lite APIs and importing these Graph Lite APIs automatically into Azure API Management.

Introduction

The Microsoft Graph API is a special API in today's digital landscape. It is basically an OData API with a CSDL endpoint, containing 14.553 API operations (yes, over fourteen thousand) as of writing and is 36.8 MB in size as OpenAPI definition. That's pretty impressive!

Microsoft offers self-made SDKs and client-code generator Kiota to programmatically interface with the Graph API, without promoting the use of the Graph API directly as a standardized OData or OpenAPI type. However, they do expose an OpenAPI definition at microsoftgraph/msgraph-metadata.

For testing proposes, Microsoft introduced some attempts to make the Graph API user-friendly, for instance with Use Postman with the Microsoft Graph API, but fails to make it a set of practical standardized OpenAPI definitions.

Graph Lite attempts to solve the monolithic nature of the Graph API, not only by making it a flexible 'lite' variant, but also by proving its effectiveness by automatically importing all Graph operations into Azure API Management.

Slicing

Graph Lite implements slicing based on OpenAPI.NET.

Side note: Microsoft also offers cli-tool Microsoft.OpenApi.Hidi, for slicing and validating, based on OpenAPI.NET as well.

Graph Lite slices the Graph API with the following rules:

  • If an operation contains get, list, check, retrieve, fetch or view, consider it a read operation. Else, consider it a modify operation.
  • Each operation has a tag with format [firstPart].[secondPart], for instance groups.site.
  • Group all read and modify operations separately using the first part of the operation tag.
  • If the group has over 500 operations, slice that group again using the second part of the operation tag.

This currently results into 244 Lite APIs, averaging about 60 operations per Lite API.

Importing into Azure API Management

Graph Lite has the ability to automatically import the whole sliced Graph API into API Management. This introduces more possibilities building a robust facade in front of the Graph API, for instance by;

  • placing specific parts of the Graph API into seperate API Management products with specific product policies;
  • abstracting authentication and finer grained authorization with credential manager;
  • more insights with the use of API Management subscription keys.

Compile

  1. Install .NET 8
  2. Replace the vars at program.cs accordingly.
  3. Build and run graph-lite-tooling with VSCode or any tool that supports .csproj files.

Generated definitions

Generated definitions can be found under generated/graphLite.

Issues

The generated OpenAPI definition from microsoftgraph/msgraph-metadata does not comply to the OpenAPI standard. It has Duplicate operationId's in the OpenAPI doc (/drives/* operations) #691. Graph Lite will throw a non-terminating information message when importing (a Lite API that has this issue) into API Management.

The OpenAPI.NET library, which is used in this project, has issues with Duplicate parameters on operation filter #1833. Graph Lite works around this by removing duplicate parameters.

Considerations

  • The PowerShell SDK slices the API into some large chunks: msgraph-sdk-powershell, but that still isn't practical to use in most cases.

  • Trying to import the OData version of the Microsoft Graph API into Azure API Management yields the following validation error:

One or more fields contain incorrect values:
Parsing error(s): Encountered the following errors when parsing the CSDL document: AlreadyDefined : An element with the name 'microsoft.graph.image' is already defined. : (38773, 14) AlreadyDefined : An element with the name 'microsoft.graph.image' is already defined. : (38777, 14) AlreadyDefined : An element with the name 'microsoft.graph.image' is already defined. : (38782, 14) AlreadyDefined : An element with the name 'microsoft.graph.image' is already defined. : (38788, 14) BadProperty : The member name 'list' cannot be used in a type with the same name. Member names cannot be the same as their enclosing type. : (25626, 18) RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3555, 26) RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3555, 26) RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3570, 26) RecordExpressionHasExtraPro...
Parsing error(s): Fail to import OData file. AlreadyDefined : An element with the name 'microsoft.graph.image' is already defined. : (38773, 14), AlreadyDefined : An element with the name 'microsoft.graph.image' is already defined. : (38777, 14), AlreadyDefined : An element with the name 'microsoft.graph.image' is already defined. : (38782, 14), AlreadyDefined : An element with the name 'microsoft.graph.image' is already defined. : (38788, 14), BadProperty : The member name 'list' cannot be used in a type with the same name. Member names cannot be the same as their enclosing type. : (25626, 18), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3555, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3555, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3570, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3570, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3585, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3585, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3600, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3600, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3615, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3615, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3630, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3630, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3645, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3645, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3660, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3660, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3675, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3675, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3690, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3690, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3705, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3705, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3720, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3720, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3735, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3735, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3750, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3750, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (3765, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (3765, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Referenceable'. : (3799, 22), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Referenceable'. : (3825, 22), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Referenceable'. : (5269, 22), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Referenceable'. : (5303, 22), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (5983, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (5983, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (6102, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (6102, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (6165, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (6165, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (6180, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (6180, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Referenceable'. : (6221, 22), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Referenceable'. : (6258, 22), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Referenceable'. : (6288, 22), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Referenceable'. : (6317, 22), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Referenceable'. : (6346, 22), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Referenceable'. : (6411, 22), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Referenceable'. : (6435, 22), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Referenceable'. : (6462, 22), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Referenceable'. : (6502, 22), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Referenceable'. : (6887, 22), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (7471, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (7471, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (7486, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (7486, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (7501, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (7501, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (7516, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (7516, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (7531, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (7531, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (15765, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (15765, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (15829, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (15829, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (15844, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (15844, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (15859, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (15859, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (15874, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (15874, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (15889, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (15889, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (15904, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (15904, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (15919, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (15919, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (15934, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (15934, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (15949, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (15949, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (15964, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (15964, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (15979, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (15979, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (15994, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (15994, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (16009, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (16009, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (16024, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (16024, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (16039, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (16039, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (16054, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (16054, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (16069, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (16069, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'Date'. : (16788, 26), RecordExpressionHasExtraProperties : The type of the record expression is not open and does not contain a property named 'RemovalDate'. : (16788, 26)

License

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

CC BY-NC-SA 4.0

About

Graph Lite simplifies the Microsoft Graph API by slicing the monolith into multiple Graph Lite APIs and importing these Graph Lite APIs automatically into Azure API Management.

Topics

Resources

License

Stars

Watchers

Forks

Languages