Skip to content

Commit 2eec12b

Browse files
authored
Merge pull request #3565 from gautamdsheth/feature/1644
Feature #1644 : Add support for batch requests in
2 parents 52302fc + d5f24e0 commit 2eec12b

File tree

3 files changed

+80
-12
lines changed

3 files changed

+80
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
4747
- Added `RequestFilesLinkEnabled` and `RequestFilesLinkExpirationInDays` to the output of `Get-PnPSite` [#3557](https://github.com/pnp/powershell/pull/3557)
4848
- Added `CoreRequestFilesLinkEnabled`, `CoreRequestFilesLinkExpirationInDays`, `OneDriveRequestFilesLinkEnabled`, `OneDriveRequestFilesLinkExpirationInDays`, `BusinessConnectivityServiceDisabled` to the output of `Get-PnPTenant` [#3557](https://github.com/pnp/powershell/pull/3557)
4949
- Added `-BusinessConnectivityServiceDisabled` parameter to `Set-PnPTenant` cmdlt to allow disabling the Business Connectivity Service [#3562](https://github.com/pnp/powershell/pull/3562)
50+
- Added support for executing the 'Invoke-PnPSPRestMethod' cmdlet in a batch [#3565](https://github.com/pnp/powershell/pull/3565)
5051
- Added `Get-PnPSiteSetVersionPolicyProgress` cmdlet which allows for getting the progress of setting a version policy for existing document libraries on a site [#3564](https://github.com/pnp/powershell/pull/3564)
5152

5253
### Fixed

documentation/Invoke-PnPSPRestMethod.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Invoke-PnPSPRestMethod -Url <String>
2222
[-Raw]
2323
[-Connection <PnPConnection>]
2424
[-ResponseHeadersVariable <String>]
25+
[-Batch <PnPBatch>]
2526
```
2627

2728
## DESCRIPTION
@@ -79,6 +80,19 @@ This example executes a GET request towards the current site collection and retu
7980

8081
It will also store the response headers values in the PowerShell variable name that you specify. Enter a variable name without the dollar sign ($) symbol.
8182

83+
### EXAMPLE 7
84+
```powershell
85+
$batch = New-PnPBatch -RetainRequests
86+
Invoke-PnPSPRestMethod -Method Get -Url "https://tenant.sharepoint.com/sites/mysite/_api/web/lists" -Batch $batch
87+
$item = "{'Title':'Test'}"
88+
Invoke-PnPSPRestMethod -Method Post -Url "https://tenant.sharepoint.com/sites/mysite/_api/web/lists/GetByTitle('Test')/items" -Content $item -Batch $batch
89+
$response = Invoke-PnPBatch $batch -Details
90+
$response
91+
```
92+
93+
This example executes a GET request to get all lists and a POST request to add an item to a list in a single batch request.
94+
It is necessary to create and invoke batch requests in the manner specified here if you want to process something later on with the response object.
95+
8296
## PARAMETERS
8397

8498
### -Content

src/Commands/Base/InvokeSPRestMethod.cs

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
using Microsoft.SharePoint.Client;
2+
using PnP.Core.Model;
3+
using PnP.Core.Services;
24
using PnP.Framework.Http;
35
using PnP.Framework.Utilities;
46
using PnP.PowerShell.Commands.Enums;
7+
using PnP.PowerShell.Commands.Model;
58
using System;
69
using System.Collections.Generic;
710
using System.Linq;
@@ -16,29 +19,36 @@ namespace PnP.PowerShell.Commands.Admin
1619
[Cmdlet(VerbsLifecycle.Invoke, "PnPSPRestMethod", DefaultParameterSetName = PARAMETERSET_Parsed)]
1720
[OutputType(typeof(PSObject), ParameterSetName = new[] { PARAMETERSET_Parsed })]
1821
[OutputType(typeof(string), ParameterSetName = new[] { PARAMETERSET_Raw })]
22+
[OutputType(typeof(void), ParameterSetName = new[] { PARAMETERSET_Batch })]
1923
public class InvokeSPRestMethod : PnPSharePointCmdlet
2024
{
2125
public const string PARAMETERSET_Parsed = "Parsed";
2226
public const string PARAMETERSET_Raw = "Raw";
27+
public const string PARAMETERSET_Batch = "Batch";
2328

2429
[Parameter(Mandatory = false, Position = 0, ParameterSetName = PARAMETERSET_Parsed)]
2530
[Parameter(Mandatory = false, Position = 0, ParameterSetName = PARAMETERSET_Raw)]
31+
[Parameter(Mandatory = false, Position = 0, ParameterSetName = PARAMETERSET_Batch)]
2632
public HttpRequestMethod Method = HttpRequestMethod.Get;
2733

2834
[Parameter(Mandatory = true, Position = 0, ParameterSetName = PARAMETERSET_Parsed)]
2935
[Parameter(Mandatory = true, Position = 0, ParameterSetName = PARAMETERSET_Raw)]
36+
[Parameter(Mandatory = true, Position = 0, ParameterSetName = PARAMETERSET_Batch)]
3037
public string Url;
3138

3239
[Parameter(Mandatory = false, ParameterSetName = PARAMETERSET_Parsed)]
3340
[Parameter(Mandatory = false, ParameterSetName = PARAMETERSET_Raw)]
41+
[Parameter(Mandatory = false, Position = 0, ParameterSetName = PARAMETERSET_Batch)]
3442
public object Content;
3543

3644
[Parameter(Mandatory = false, ParameterSetName = PARAMETERSET_Parsed)]
3745
[Parameter(Mandatory = false, ParameterSetName = PARAMETERSET_Raw)]
46+
[Parameter(Mandatory = false, Position = 0, ParameterSetName = PARAMETERSET_Batch)]
3847
public string ContentType = "application/json";
3948

4049
[Parameter(Mandatory = false, ParameterSetName = PARAMETERSET_Parsed)]
4150
[Parameter(Mandatory = false, ParameterSetName = PARAMETERSET_Raw)]
51+
[Parameter(Mandatory = false, Position = 0, ParameterSetName = PARAMETERSET_Batch)]
4252
public string Accept = "application/json;odata=nometadata";
4353

4454
[Parameter(Mandatory = false, ParameterSetName = PARAMETERSET_Raw)]
@@ -48,6 +58,9 @@ public class InvokeSPRestMethod : PnPSharePointCmdlet
4858
[Parameter(Mandatory = false, ParameterSetName = PARAMETERSET_Raw)]
4959
public string ResponseHeadersVariable;
5060

61+
[Parameter(Mandatory = false, Position = 0, ParameterSetName = PARAMETERSET_Batch)]
62+
public PnPBatch Batch;
63+
5164
protected override void ExecuteCmdlet()
5265
{
5366
if (Url.StartsWith("/"))
@@ -56,21 +69,37 @@ protected override void ExecuteCmdlet()
5669
Url = UrlUtility.Combine(ClientContext.Url, Url);
5770
}
5871

59-
var method = new HttpMethod(Method.ToString());
60-
61-
var httpClient = PnPHttpClient.Instance.GetHttpClient(ClientContext);
72+
var method = new HttpMethod(Method.ToString().ToUpper());
6273

6374
var requestUrl = Url;
6475

76+
if (string.IsNullOrEmpty(Accept))
77+
{
78+
Accept = "application/json;odata=nometadata";
79+
}
80+
81+
if (string.IsNullOrEmpty(ContentType))
82+
{
83+
ContentType = "application/json";
84+
}
85+
86+
if (ParameterSpecified(nameof(Batch)))
87+
{
88+
CallBatchRequest(method, requestUrl);
89+
}
90+
else
91+
{
92+
CallSingleRequest(method, requestUrl);
93+
}
94+
}
95+
96+
private void CallSingleRequest(HttpMethod method, string requestUrl)
97+
{
98+
var httpClient = PnPHttpClient.Instance.GetHttpClient(ClientContext);
6599
bool isResponseHeaderRequired = !string.IsNullOrEmpty(ResponseHeadersVariable);
66100

67101
using (HttpRequestMessage request = new HttpRequestMessage(method, requestUrl))
68102
{
69-
if (string.IsNullOrEmpty(Accept))
70-
{
71-
Accept = "application/json;odata=nometadata";
72-
}
73-
74103
request.Headers.Add("accept", Accept);
75104

76105
if (Method == HttpRequestMethod.Merge)
@@ -88,10 +117,7 @@ protected override void ExecuteCmdlet()
88117

89118
if (Method == HttpRequestMethod.Post || Method == HttpRequestMethod.Merge || Method == HttpRequestMethod.Put || Method == HttpRequestMethod.Patch)
90119
{
91-
if (string.IsNullOrEmpty(ContentType))
92-
{
93-
ContentType = "application/json";
94-
}
120+
95121
var contentString = Content is string ? Content.ToString() :
96122
JsonSerializer.Serialize(Content, new JsonSerializerOptions() { ReferenceHandler = ReferenceHandler.IgnoreCycles, WriteIndented = true });
97123
request.Content = new StringContent(contentString, System.Text.Encoding.UTF8);
@@ -150,5 +176,32 @@ protected override void ExecuteCmdlet()
150176
}
151177
}
152178
}
179+
180+
private void CallBatchRequest(HttpMethod method, string requestUrl)
181+
{
182+
var web = PnPContext.Web;
183+
string contentString = null;
184+
if (ParameterSpecified(nameof(Content)))
185+
{
186+
contentString = Content is string ? Content.ToString() :
187+
JsonSerializer.Serialize(Content, new JsonSerializerOptions() { ReferenceHandler = ReferenceHandler.IgnoreCycles, WriteIndented = true });
188+
189+
}
190+
191+
Dictionary<string, string> extraHeaders = new() { { "Accept", Accept } };
192+
193+
if (Method == HttpRequestMethod.Merge)
194+
{
195+
extraHeaders.Add("X-HTTP-Method", "MERGE");
196+
}
197+
198+
if (Method == HttpRequestMethod.Merge || Method == HttpRequestMethod.Delete)
199+
{
200+
extraHeaders.Add("IF-MATCH", "*");
201+
}
202+
extraHeaders.Add("Content-Type", ContentType);
203+
204+
web.WithHeaders(extraHeaders).ExecuteRequestBatch(Batch.Batch, new ApiRequest(method, ApiRequestType.SPORest, requestUrl, contentString));
205+
}
153206
}
154207
}

0 commit comments

Comments
 (0)