How to Convert MS SharePoint $metadata XML Response into Standard Odata JSON in NodeJS? - node.js

I am working on MS SharePoint 2013 integration and in my use case I want to work on JSON data only.
I am able to convert all the API XML responses like File, Folder, List, ListItem, etc into OData JSON using Node Module - datajs_vanilla, but I am not able to convert https://mysite/_api/$metadata into OData JSON.
I am getting below error while executing datajs for $metadata endpoint:
error:{"message":"no handler for data"}
Below is my code snippet:
OData.read({
requestUri: 'https://example.com/_api/$metadata',
headers: {
'Authorization': 'Bearer token_value',
'Accept':'application/xml;charset=utf-8'
}
}, function (data, response) {
console.log("Operation succeeded."+JSON.stringify(data));
}, function (err) {
console.log("Error occurred " + JSON.stringify(err));
});
I am missing something here to convert into JSON?
or
Could you please suggest me possible solution to convert edmx sharepoint $metadata XML response into OData JSON using node module?
Thanks.

See answer for similar question Get OData $metadata in JSON format .
Metadata document is not defined using OData atom/xml format that's why datajs vanilla is failing to parse it.
Metadata format is CSDL format. Example of metadata doc - http://services.odata.org/V4/TripPinServiceRW/$metadata.
Usually metadata used for discovery and client generation since it has type info and all entity relations. Having service responses being serialized to json and service documentation in json should be sufficient for you to work with service.

Related

How to get file comments using Sharepoint rest api

I'm using the following api to successfully get file data:
https://acme.sharepoint.com/sites/my-site/_api/Web/Lists(guid'xxx')/files('yyy')
This is a docx file on which I've posted comments using the web console.
How can I fetch these comments using the rest api? I tried appending /comments to the url, but I'm getting the following 404 error:
{
"error": {
"code": "-1, Microsoft.SharePoint.Client.ResourceNotFoundException",
"message": {
"lang": "en-US",
"value": "Cannot find resource for the request Comments."
}
}
}
The Comments() endpoint currently exists only under the Items() endpoint and not under the Files() endpoint.
Basically, you can access the Comments() functionality only under the below endpoint:
GET https://{site_url}/_api/web/lists/GetByTitle({list_title})/items({item_id})/Comments
You can easily test the above in a PowerAutomate scenario with a Send Http Request to SharePoint actions.
In the below example I attempt to target the file in the document library:
On the other hand, if I attempt to target the file based on the List Item Id that it got in the document library I will get the below response:
As you can see from the above, I am also able to target a specific comment that I left.
Please take note of the below
The Comments() endpoint is not available for MS resources, meaning docx, excels and such files. It is only available for non-MS resource files like pdfs, txts and so on. I am not sure why this rule is in effect but, my best guess would be because there is a "commenting" functionality provided within a Word Document, for example.
You could find a bit more info about the above here.

Azure Build Pipeline - Pause and Enable DefinitionQueueStatus change REST API

We have many dozens of build pipelines and we want to pause and resume (re-enable) build pipelines from a simple webapp interface as we are making config changes frequently. Here is the MS doc explaining this API:
https://learn.microsoft.com/en-us/rest/api/azure/devops/build/builds/update%20build?view=azure-devops-rest-5.0#definitionqueuestatus
From this documentation, it appears I need to hit the REST API and change/toggle the DefinitionQueueStatus -- however, this documentation only shows a sample for a build specific operation, whereas I want to pause then re-enable the entire build pipeline. What is the proper way to make this call?
I'm using fetch - and I've tried many dozen formats in the call - the 'ourorg' and 'ourproject' are correct (we use this call structure for many other calls), but all fails for this call below. I grabbed the 'definitionID' from the URL I can visibly see when in the Azure devops portal on the specific build pipeline page, and I'm using it for the {buildID} as I don't know what else to put there. Any guidance to help here is appreciated - I don't need to use fetch btw - any working sample will help here:
fetch(https://dev.azure.com/our_org/our_projectname/_apis/build/builds/definitionId=1593?retry=true&api-version=5.0 {
method: 'PATCH ',
credentials: 'same-origin',
body: 'DefinitionQueueStatus: "Enabled"'
}).then(function(response) {
console.log(response);
})
It seems that the body is incorrect in your post. Here is sample about how to use POSTMAN to access Azure DevOps Services REST APIs.
Generate the PAT, and then record the token, it is important to use to authorization, please see this document.
Create a new request in POSTMAN, it is recommended to put the request in a collection for Azure DevOps Services REST API;
Select the authorization as Basic Auth, you can input the username as any value, and the password as the token which is generated in step1.
Basic Auth
Set the REST API which you want to use,and select the request method type(GET,POST,FETCH ....), here you use https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}?api-version=5.0.
In the Body tab, you can set the request body as raw in json format, and input the value as following:
{
"buildNumber":"#20190607.2",
"buildNumberRevision":1,
"definition":
{
"id":1,
"createdDate":null,
"queueStatus":"paused"
}
}
Everthing is ready now, you can send the request, if sccuess, you will get the response from the REST API.
In your post, the body content is incorrect, the Request Body should meet the format in the REST API document. The DefinitionQueueStatus is a type in definitions. In addition, if you send the request with parameter retry, you will get the message The request body must be empty when the retry parameter is specified..

Logic App - PartitionKey extracted from document doesn't match the one specified in the header

I ran into this error while building a Logic App in Azure. The solution to this DocumentDB REST API: PartitionKey extracted from document doesn't match is not working.
My logic app receives a POST request with the raw JSON data, and then sends it to a Cosmos "Create or Update Document" step. In there, I am able to specify my DB, and for my inputs, I have body and headers like so:
...
"inputs": {
"body": "#triggerBody()",
"headers": {
"x-ms-documentdb-partitionkey": "#triggerBody()?['date']"
},
...
}
...
My JSON data looks like this:
{
"id": "20190106",
"date": "20190106",
...
}
In the error output, it literally shows my PartitionKey as 20190106, so the #triggerBody()?['date'] seems to have worked.
Any ideas?
Don't forget to add Content-Type: application/json in the Post request.(mentioned in this thread)
Cosmos DB connector:
Post Request:
Output:
If your partition key is date, then try passing the value of date [“20190106"] (use the square brackets) in the partition key header. This worked for me 2 days ago using Rest API for CosmoDb.
The answer is that Logic Apps do not support the Mongo API. Yes, there's a workaround, as in the Logic App can pass data from one endpoint to a serverless function that then writes to Mongo.
Problems inserting document with Mongodb and Logic Apps

XML Request from strong-soap

I am using strong-soap, and it is working well.
How do I locate the request and response XML that strong-soap has generated?
I would like to review and possibly log the XML, so that I can use the converted XML while testing the WSDL directly.
It may be late, but for people that may have the same problem in the future, here is how you can log your inbound and outbound requests in XML format:
server = soap.listen(...)
server.log = function(type, data) {
// type is 'received' or 'replied'
// data is the xml sent or received
};
References: strong-soap Github repo

AWS Lambda fails to return PDF file

I have created a lambda function using serverless. This function is fired via API Gateway on a GET request and should return a pdf file from a buffer. I'm using html-pdf to create the buffer and trying to return the pdf file with the following command
let response = {
statusCode: 200,
headers: {'Content-type' : 'application/pdf'},
body: buffer.toString('base64'),
isBase64Encoded : true,
};
return callback(null, response);
but the browser is just failing to load the pdf, so I don't know exactly how to return the pdf file directly to the browser. Could'nt find a solution for that.
well, I found the answer.
The settings in my response object are fine, I just had to manually change the settings in API Gateway for this to work in the browser. I have added "*/*" to binary media types under the binary settings in API Gateway console
API GATEWAY
just log into your console
choose your api
click on binary support in the dropdown
edit binary media type and add "*/*"
FRONTEND
opening the api url in new tab (target="_blank"). Probably the browser is handling the encoded base 64 response, In my case with chrome, the browser just opens the pdf in a new tab exactly like I want it to do.
After spending several hours on this I found out that if you set Content handling to Convert to binary (CONVERT_TO_BINARY) the entire response has to be base64, I would otherwise get an error: Unable to base64 decode the body.
Therefore my response now looks like:
callback(null, buffer.toString('base64'));
The Integration response:
The Method response:
And Binary Media Types:
If you have a gigantic PDF, then it will take a long time for Lambda to return it and in Lambda you are billed per 100ms.
I would save it to S3 first then let the Lambda return the S3 url to the client for downloading.
I was having a similar issue where pdf where downloaded as base64 and started happening when changed the serverles.yml file from:
binaryMediaTypes:
- '*/*'
to
binaryMediaTypes:
- 'application/pdf'
- '....other media types'
The issue is because the way AWS implemented this feature. From aws documentation here:
When a request contains multiple media types in its Accept header, API
Gateway honors only the first Accept media type. If you can't control
the order of the Accept media types and the media type of your binary
content isn't the first in the list, add the first Accept media type
in the binaryMediaTypes list of your API. API Gateway handles all
content types in this list as binary.
Basically if the first media type contained in the accept request header is not in your list in binaryMediaTypes then you will get base64 back.
I checked the request in the browser and the first media type in the accept header was text/html so I got it working after changing my settings to:
binaryMediaTypes:
- 'application/pdf'
- '....other media types'
- 'text/html'
Hope this helps anyone with the same issue.
Above solution is only for particular content-type. You can't more content type.
Follow only below two-step to resolve multiple content type issue.
Click on the checkbox of Use Lambda Proxy integration
API gateway --> API --> method --> integration request
Create your response as
let response = {
statusCode: 200,
headers: {
'Content-type': 'application/pdf',//you can change any content type
'content-disposition': 'attachment; filename=test.pdf' // key of success
},
body: buffer.toString('base64'),
isBase64Encoded: true
};
return response;
Note* - It is not secure
Instead of doing all this. It's better to use serverless-apigw-binary plugin in your serverless.yaml file.
Add
plugins:
- serverless-apigw-binary
custom:
apigwBinary:
types:
- "application/pdf"
Hope that will help someone.

Resources