Skip to content

Conversation

@tinestaric
Copy link
Contributor

@tinestaric tinestaric commented Dec 15, 2025

Summary

Add Microsoft Graph API Support to SharePoint Connector

BC Idea

Implements Idea #21d4bf5c-d7b4-f011-aa43-7c1e52a6c1f4

Problem Statement

Business Central limits the maximum HTTP response content size to 150 MB by default (controlled by the NavHttpClientMaxResponseContentSize server setting). This limitation causes file downloads from SharePoint to fail for files larger than this threshold.

While chunked downloads would solve this issue, SharePoint REST APIs do not support chunked downloads (only uploads). Microsoft Graph API, however, does support this capability.

Solution

This PR introduces Microsoft Graph API support as an alternative implementation alongside the existing SharePoint REST API, with a backward-compatible toggle to switch between the two.

Changes

  • New field: Added "Use Graph API" toggle in ExtSharePointAccount.Table.al and ExtSharePointAccount.Page.al to control API selection
  • Improved UX: Updated tooltips to clarify folder path requirements for both APIs
  • Refactored implementation: Modified ExtSharePointConnectorImpl.Codeunit.al to route operations based on API selection
  • New codeunits:
    • ExtSharePointGraphHelper.Codeunit.al: Encapsulates Graph API operations for files and directories
    • ExtSharePointRestHelper.Codeunit.al: Encapsulates existing REST API operations
  • Bug fix: Fixed certificate parameter assignment in GraphAuthClientCredentials.Codeunit.al that prevented certificate-based authentication from working correctly

Backward Compatibility

The existing SharePoint REST API implementation remains the default option, ensuring no breaking changes for current users. The Graph API can be enabled per account configuration.

Dependencies

Depends on SharePoint module additions in the System Application (see #3655)

Benefits

  • Removes file size limitations: Graph API supports downloading files larger than 150 MB through chunked downloads
  • Flexibility: Users can choose the API that best fits their requirements
  • Clean permissions model: App registration can use either SharePoint REST or Graph API permissions without mixing
  • Backward compatible: Existing implementations continue to work without changes

Work Item(s)

Fixes #5383

Fixes AB#612932

Tine Staric added 2 commits December 15, 2025 12:10
- Introduced a new field "Use Graph API" in Ext. SharePoint Account table and page to toggle between SharePoint REST API and Microsoft Graph API.
- Updated tooltips for clarity on folder paths for both APIs.
- Refactored Ext. SharePoint Connector implementation to utilize Graph API for file operations, including ListFiles, GetFile, CreateFile, CopyFile, MoveFile, FileExists, and DeleteFile.
- Created Ext. SharePoint Graph Helper codeunit to encapsulate Graph API logic for file and directory operations.
- Added Ext. SharePoint REST Helper codeunit for existing REST API operations.
- Ensured compatibility with existing functionality while providing an option to leverage Microsoft Graph API for enhanced performance and capabilities.
@tinestaric tinestaric requested a review from a team as a code owner December 15, 2025 11:12
Copilot AI review requested due to automatic review settings December 15, 2025 11:12
@github-actions github-actions bot added AL: System Application AL: Apps (W1) Add-on apps for W1 From Fork Pull request is coming from a fork labels Dec 15, 2025
@github-actions github-actions bot added the Linked Issue is linked to a Azure Boards work item label Dec 15, 2025
@github-actions github-actions bot added this to the Version 28.0 milestone Dec 15, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds Microsoft Graph API support to the SharePoint Connector as an alternative to the existing SharePoint REST API implementation. The enhancement addresses Business Central's 150 MB HTTP response limit by enabling chunked downloads through Microsoft Graph API, which supports this capability unlike SharePoint REST APIs.

Key Changes:

  • Introduces a "Use Graph API" toggle to switch between REST and Graph API implementations
  • Refactors connector logic to route operations based on API selection
  • Adds new helper codeunits to encapsulate Graph and REST API operations separately

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
ExtSharePointAccount.Table.al Adds "Use Graph API" boolean field with improved tooltips explaining path requirements for both APIs
ExtSharePointAccount.Page.al Updates UI to display the new "Use Graph API" toggle
ExtSharePointConnectorImpl.Codeunit.al Implements routing logic to delegate operations to appropriate helper based on API selection
ExtSharePointGraphHelper.Codeunit.al New codeunit encapsulating all Microsoft Graph API file operations
ExtSharePointRestHelper.Codeunit.al New codeunit encapsulating existing SharePoint REST API operations
GraphAuthClientCredentials.Codeunit.al Bug fix for certificate parameter assignment in authentication

Note: Since this PR depends on System Application changes (PR #3655) and I cannot view the actual diff of changes, I cannot provide specific code-level review comments. The PR appears well-structured based on the description, maintains backward compatibility by keeping REST API as the default, and follows a clean separation of concerns by creating dedicated helper codeunits for each API implementation.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@tinestaric
Copy link
Contributor Author

@IceOnly @StefanSosic
If you're not already enjoying the holidays, as two of the most involved with the connectors, I'd appreciate your reviews here.

@JesperSchulz
While adding GraphAPI support, I also identified a bug in one of the SystemApp modules. I wasn't sure whether to open a separate PR for that bug fix or include it in this one as well.

Copy link
Contributor

@IceOnly IceOnly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!
I’ll try to test it at the end of the week.
Only suggestion:
It might make sense to replace the "Use Graph API" boolean with an enum, add an interface, and use that interface to select the correct helper. This could make the design more flexible and easier to extend later.

@JesperSchulz
Copy link
Contributor

@IceOnly @StefanSosic If you're not already enjoying the holidays, as two of the most involved with the connectors, I'd appreciate your reviews here.

@JesperSchulz While adding GraphAPI support, I also identified a bug in one of the SystemApp modules. I wasn't sure whether to open a separate PR for that bug fix or include it in this one as well.

Including bug fix here should be fine!

@StefanSosic
Copy link
Contributor

@IceOnly @StefanSosic If you're not already enjoying the holidays, as two of the most involved with the connectors, I'd appreciate your reviews here.

@JesperSchulz While adding GraphAPI support, I also identified a bug in one of the SystemApp modules. I wasn't sure whether to open a separate PR for that bug fix or include it in this one as well.

I will also take a look. No holidays for me yet 😊

@tinestaric
Copy link
Contributor Author

Looks good! I’ll try to test it at the end of the week. Only suggestion: It might make sense to replace the "Use Graph API" boolean with an enum, add an interface, and use that interface to select the correct helper. This could make the design more flexible and easier to extend later.

Thanks!
I've actually been juggling the idea of the interface, but I was a bit reluctant. I couldn't foresee any additional options beyond the Rest and Graph APIs for connecting to SharePoint. And if there are only two, do I want to add the additional abstraction for abstraction's sake.

This comment isn't a no; I'm open to switching to an interface, but it's more of a discussion. Where would you see it extended in the future?

@JesperSchulz JesperSchulz added the Integration GitHub request for Integration area label Dec 17, 2025
}
}
field(Disabled; Rec.Disabled) { }
field("Use Graph API"; Rec."Use Graph API") { }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If someone selects or deselects this field then Base Relative Folder Path maybe needs to be updated.
I'm not sure about the best behaviour.
The less intrusive would be a notification to check if the Base Relative Folder Path is still correct setup.

This comment is explicit for the Card page that someone opens for an existing setup.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pri-kise I now added a warning. But mostly in allot of cases the field is blanket out so the user need to fill it in again.

end;
}

field("Use Graph API"; Rec."Use Graph API")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand why you added the field at the end.
It's a new setup field.

Since this fields has an influence on the Base Relative Folder Path I would suggest to add this field before the field Base Relative Folder Path. Otherwise a user might need to updat the path field once again afterwards.

I did even thought if it would be better to have an additional step before the common setup for both where a user must select this new option. (Currently I'm not sure if this would be really better)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks!

JesperSchulz
JesperSchulz previously approved these changes Jan 7, 2026
Copy link
Contributor

@JesperSchulz JesperSchulz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me! Once Kilian's comments have been addressed, I think we're ready to push this forward!

if Path = '' then
Path := '/';

SharePointGraphClient.GetItemsByPath(Path, GraphDriveItem);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In all other calls, we use the return value:

        Response := SharePointGraphClient.DeleteItemByPath(Path);

        if not Response.IsSuccessful() then
            ShowError(Response);

Just checking that you're deliberately not doing that here.


internal procedure ListFiles(SharePointAccount: Record "Ext. SharePoint Account"; Path: Text; FilePaginationData: Codeunit "File Pagination Data"; var TempFileAccountContent: Record "File Account Content" temporary)
var
GraphDriveItem: Record "SharePoint Graph Drive Item";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In ListDirectories you're using a temp record. Here not. Is that intentional?

@Bertverbeek4PS
Copy link
Contributor

@JesperSchulz since @tinestaric is on holiday for 3 months I have talked to him that I would resolve any comments.
(it is a request from the extension project of 4PS)
But I'm no maintainer at his branche 👎 . So how can we proceed?

@tinestaric
Copy link
Contributor Author

@Bertverbeek4PS made you a collaborator on the fork. :)

@Bertverbeek4PS
Copy link
Contributor

@Bertverbeek4PS made you a collaborator on the fork. :)

Thanks allot @tinestaric

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AL: Apps (W1) Add-on apps for W1 AL: System Application From Fork Pull request is coming from a fork Integration GitHub request for Integration area Linked Issue is linked to a Azure Boards work item

Projects

None yet

6 participants