When developing for SharePoint, optimizing your network requests is crucial for building responsive applications. A common challenge developers face is needing to list the contents of a directory—both the files and the subfolders—without making multiple round-trips to the server. By default, the SharePoint REST API often separates these entities, but you can actually retrieve everything you need in a single call.
In this guide, you will learn how to use the SharePoint REST API to get all files and folders efficiently. We will cover the OData $expand method for simple folder structures and the GetItems method for more complex, recursive requirements.
Using the $expand Operator for Efficient Requests
The most straightforward way to retrieve both files and folders in a single request is to use the $expand OData operator. When you target a specific folder via its server-relative URL, you can tell SharePoint to "expand" the related collections of files and folders so they are included in the initial response.
This method is ideal when you are looking at a specific directory level and want to avoid the overhead of two separate calls to .../Folders and .../Files endpoints.
Here is the endpoint structure:
https://{your-domain}/_api/Web/GetFolderByServerRelativeUrl('/sites/your-site/Library/FolderName')?$expand=Folders,Files
By adding ?$expand=Folders,Files to your query, the JSON response will contain two arrays: one for Folders and one for Files. This significantly reduces the latency of your application, especially on slower connections.
Handling the Response Data in JavaScript
Once you have made the call, you need to process the data. Modern JavaScript provides several ways to iterate through these collections. Below is an example using $.getJSON (jQuery) that demonstrates how to access the returned file and folder names.
var folderUrl = '/documents/2015';
var url = _spPageContextInfo.webServerRelativeUrl + "/_api/Web/GetFolderByServerRelativeUrl('" + folderUrl + "')?$expand=Folders,Files";
$.getJSON(url, function(data) {
// Iterating through files
data.Files.forEach(function(file) {
console.log("File Name: " + file.Name);
});
// Iterating through folders
data.Folders.forEach(function(folder) {
console.log("Folder Name: " + folder.Name);
});
});
If you simply need an array of names for your UI components, you can use the .map() function to transform the data objects into simple strings:
$.getJSON(url, function(data) {
var filenamesArr = data.Files.map(function(file) {
return file.Name;
});
var foldernamesArr = data.Folders.map(function(folder) {
return folder.Name;
});
console.log("All Files:", filenamesArr);
console.log("All Folders:", foldernamesArr);
});
Advanced Retrieval with GetItems and CAML Queries
While the $expand method is excellent for simple scenarios, it is limited to the immediate children of the specified folder. If you need to retrieve items from a specific subfolder based on more complex logic, or if you need to filter by metadata, using GetItems with a CAML query is the better approach.
This method treats the folder contents as list items. This is particularly useful when you want to filter by the FileDirRef (the directory reference).
/_api/web/Lists/GetByTitle('DocLib')/GetItems(query=@v1)?$select=Title,File/Name&$expand=File&@v1={"ViewXml":"<View Scope='RecursiveAll'><Query><Where><Eq><FieldRef Name='FileDirRef' /><Value Type='Text'>/SubSite1/DocLib/SubFolder1</Value></Eq></Where></Query></View>"}
In this example, we use the RecursiveAll scope, but we filter specifically for the directory path. This allows you to get both folders and files as a flat list of items, which can then be filtered or sorted using standard array methods.
Recursive Retrieval Across All Subdirectories
One of the most powerful features of the SharePoint REST API is the ability to perform a recursive crawl of a document library. If your goal is to get every file and folder within a specific branch of your library—regardless of how deep the nesting goes—you should use the FolderServerRelativeUrl property within a GetItems call.
/_api/web/Lists/GetByTitle('DocLibrary')/GetItems(query=@v1)?$select=Title,File/Name&$expand=File&@v1={"FolderServerRelativeUrl" : "/sites/marketing/Shared Documents/Campaigns", "ViewXml":"<View Scope='RecursiveAll'></View>"};
Why use this over $expand?
- Recursion:
$expandonly goes one level deep.RecursiveAllgoes through the entire tree. - Metadata: Using
GetItemsallows you to retrieve custom column values (like 'Status' or 'Department') at the same time as the file names. - Performance: For very large libraries, CAML queries are often more performant than expanding large OData collections.
Frequently Asked Questions
Can I filter the results within the $expand call?
While you can use $select to limit the properties returned (e.g., ?$select=Files/Name,Folders/Name&$expand=Files,Folders), standard OData filtering ($filter) on the expanded collections themselves is limited in the SharePoint REST API. If you need complex filtering, use the GetItems approach with a CAML query.
Is there an item limit for these calls?
Yes. Like all SharePoint REST calls, you are subject to the List View Threshold (typically 5,000 items). If your folder contains more than 5,000 items, you will need to implement pagination using the $top and $skiptoken parameters or refine your query to return fewer results.
Does this work in SharePoint Online and SharePoint On-Premises?
Yes, the $expand and GetItems methods are supported in SharePoint Online (Microsoft 365) as well as SharePoint 2013, 2016, and 2019. However, ensure that the server-relative URLs are correctly formatted for your specific environment.
Wrapping Up
Retrieving files and folders in one call is a simple yet effective optimization for any SharePoint developer. For most UI tasks where you are displaying the contents of a single folder, the $expand=Folders,Files method is the cleanest and most readable solution. For complex data processing, recursive searches, or metadata-heavy requirements, the GetItems CAML approach provides the flexibility you need.
By reducing the number of API calls, you not only make your application faster but also reduce the load on your SharePoint environment, leading to a better overall user experience.