I am writing an API to consume data from another 3rd party application (RapidPro). Sadly, the third party application sends its JSon enclosed in single quotes which Laravel does not seem to understand, when I return the $request object, I get an empty array [].
Is there any way I can accept the JSon as it is with single quotes as I cannot possibly change the third party API?
The JSon to parse is this one:
{
'contact': {
'uuid': 'e65ef92b-24ce-459b-a8fd-beb042330eb0',
'name': 'UserName',
'urn': 'tel: +12000000000'
},
'flow': {
'name': 'MyFlow',
'uuid': 'da5d6c42-a818-481b-b91c-e9622dafe8be'
},
'path': [],
'results': {},
'run': {
'uuid': '2a2f709f-d114-413c-a865-d960cea73981',
'created_on': '2018-05-23T19: 06: 03.308191+00: 00'
},
'input': {
'urn': 'tel: +12000000100',
'text': 'What I wanna say',
'attachments': []
}
}
I user the following route in receiving the API call, it works and takes it to the controller:
Route::post('sms', 'UserController#sms')->name('sms.store');
The SMS controller for this demo let's just write it to a local file and send back the results to be viewed in Insomnia where the demo call is made:
public function sms(Request $request)
{
Storage::put('sms.txt', $request);
return $request;
}
When I post the JSON in via Insomnia to my server I get an empty response, when I use double quotes however; the posted JSON is thrown back nicely.
Turns out, in RapidPro debugger the jSON is shown using single-quotes but in actual POST it uses double quotes. What I had wrong was the AUTH. I had to include some header for Laravel's Basic Once authentication.
Related
I am trying to get data using GDC portal api. As it is shown in GDC API, to send an HTTP GET request, we need to have a format similar to:
https://api.gdc.cancer.gov/files?filters=%7B%22op%22%3A%22and%22%2C%22content%22%3A%5B%7B%22op%22%3A%22in%22%2C%22content%22%3A%7B%22field%22%3A%22cases.submitter_id%22%2C%22value%22%3A%5B%22TCGA-CK-4948%22%2C%22TCGA-D1-A17N%22%2C%22TCGA-4V-A9QX%22%2C%22TCGA-4V-A9QM%22%5D%7D%7D%2C%7B%22op%22%3A%22%3D%22%2C%22content%22%3A%7B%22field%22%3A%22files.data_type%22%2C%22value%22%3A%22Gene%20Expression%20Quantification%22%7D%7D%5D%7D&format=tsv&fields=file_id,file_name,cases.submitter_id,cases.case_id,data_category,data_type,cases.samples.tumor_descriptor,cases.samples.tissue_type,cases.samples.sample_type,cases.samples.submitter_id,cases.samples.sample_id,analysis.workflow_type,cases.project.project_id,cases.samples.portions.analytes.aliquots.aliquot_id,cases.samples.portions.analytes.aliquots.submitter_id&size=1000
Which is a format from json payload as:
{
"filters":{
"op":"and",
"content":[
{
"op":"in",
"content":{
"field":"cases.submitter_id",
"value":[
"TCGA-CK-4948",
"TCGA-D1-A17N",
"TCGA-4V-A9QX",
"TCGA-4V-A9QM"
]
}
},
{
"op":"=",
"content":{
"field":"files.data_type",
"value":"Gene Expression Quantification"
}
}
]
},
"format":"tsv",
"fields":"file_id,file_name,cases.submitter_id,cases.case_id,data_category,data_type,cases.samples.tumor_descriptor,cases.samples.tissue_type,cases.samples.sample_type,cases.samples.submitter_id,cases.samples.sample_id,analysis.workflow_type,cases.project.project_id,cases.samples.portions.analytes.aliquots.aliquot_id,cases.samples.portions.analytes.aliquots.submitter_id",
"size":"1000"
}
I wanna add more fields to the payload json and get the equivalent http query string format. I have tried some online convertors, like: JSON-to-String Convertor. Copying the above JSON gives me the below result:
"{\"filters\":{\"op\":\"and\",\"content\":[{\"op\":\"in\",\"content\":{\"field\":\"cases.submitter_id\",\"value\":[\"TCGA-CK-4948\",\"TCGA-D1-A17N\",\"TCGA-4V-A9QX\",\"TCGA-4V-A9QM\"]}},{\"op\":\"=\",\"content\":{\"field\":\"files.data_type\",\"value\":\"Gene Expression Quantification\"}}]},\"format\":\"tsv\",\"fields\":\"file_id,file_name,cases.submitter_id,cases.case_id,data_category,data_type,cases.samples.tumor_descriptor,cases.samples.tissue_type,cases.samples.sample_type,cases.samples.submitter_id,cases.samples.sample_id,analysis.workflow_type,cases.project.project_id,cases.samples.portions.analytes.aliquots.aliquot_id,cases.samples.portions.analytes.aliquots.submitter_id\",\"size\":\"1000\"}"
So, I tried to get data using the generated string by adding
https://api.gdc.cancer.gov/files?
to the beginning of that. But, running this, gives me a different output. So, how can I convert the JSON to exactly what is given in GDC website? Sorry, I am very new to API and their usages.
I have an endpoint that is expecting an encrypted value and I am trying to test in Postman but can't figure out how to send it as it has multiple sets of double quotes. How can I properly escape the quotes so the request can be send as raw JSON in the post body.
Trying to send
{
"data": "a:{"iv":"abcdeg1234567","encryptedData":"c37590bb7c5ce..."}"
}
If posted as above in Postman Body/raw it errors out. I have tried using \\\ or doubling up on quotes ""some value"" but it doesn't work with the object I want to send as a string.
I tried the solutions shown here: https://sqa.stackexchange.com/questions/42483/how-to-send-double-quotes-in-postman-csv-data-file but they did not work for me as I am trying to send different data.
you json is not valid but your you can fix
{
"data": "{\"a\" :{\"iv\":\"abcdeg1234567\",\"encryptedData\":\"c37590bb7c5ce...\"}}"
}
after this you can read data
var jp=JObject.Parse(json);
var data=JObject.Parse((string) jp["data"] );
or better
jp["data"]=JObject.Parse((string) jp["data"] );
var fixeJson=jp.ToString();
final result
{
"data": {
"a": {
"iv": "abcdeg1234567",
"encryptedData": "c37590bb7c5ce..."
}
}
}
I want to POST the following JSON-object via Postman:
{
"title": "test_title",
"date": "2021-12-31",
"attachments": [
{
"name": "test_attachment"
}
]
}
This works perfectly fine, when using Postman's raw input form for the request-body: I get a "201 Created"-response back.
However, when using the form-data to POST the data, I get the error "Invalid data. Expected a dictionary, but got str." (see also screenshot below) What am I doing wrong here? I tried all kind of other versions to enter the attachment-key:value pair but nothing worked so far
I managed to make it work! (note: I added some additional fields compared to the screenshot in question. See below for details:
You did nothing wrong.
If you want to make a request with json object, then you go with raw type (json) in postman.
If you want to upload file, then you use form-data
One more thing, status 201 means the request is succeed, your object has been created.
var express = require('express')
const multer = require('multer')
const upload = multer()
var app = express()
app.use(express.json());
app.post('/test',upload.none(), function (req, res, next) {
res.send(req.body)
})
app.listen(80, function () {
console.log('web server listening on port 80')
})
Above is a sample endpoint which works with both form-data and json , just do a post to http://localhost:80/test with both form data and raw json
you can see both will get parsed correclty
APIs are just abstraction , its like a function that takes in many attribute, how you parse it depends on the implementation ( how the api function is written) .
so answer is "Talk to the developer" on how the API is implemented and what it is supporting
I'm having issue in placing json into form format the way Daniel did in Postman. Need help in figuring out what is it required to place the cascaded json objects into form data format. Please see here that I'm trying to accomplish.
JSON Format (to be filled into Postman form-data section:
{
"primary_object": {
"child_object_1": [{"id": 12345678, "value": "abc"},{"id": 87654321, "value": "xyz"}],
"child_object_2": [
"first_val",
"second_val"
]
}
}
The task is rather simple, I request the endpoint with POST request (https://banana.com/endpoint/swap.php), give it my form: { banana: ["China's Red", "Sweden's Gray"], apples: [] } and send it.
However, the Request module for NodeJS that I am using does not encode the empty array (in this case "apples") and if the endpoint doesn't receive the "apples" array, it returns an error - "Invalid JSON". I have tried doing this with already encoded strings and it works just fine. I am also unable to stringify my json and then use encodeURI(), as it will then give "bananas" and "apples" quotes around them, which will get encoded - needless to say, the endpoint doesn't like that either.
I'd really appreciate if somebody could at least point me in the right direction. As I am unsure on how to proceed with this, without creating some awful spaghetti code.
data = { banana: ["China's Red", "Sweden's Gray"], apples: [] }
result = JSON.parse(JSON.stringify(data)) .
You wouldn't get double around banana and apple and if you need to access then access it
console.log(result.banana)
console.log(result.apple)
So if you need to feed this result in post request then -
url = 'your url';
const options = {
url: url,
method: 'POST',
headers: {
Accept: 'application/json',
'Accept-Charset': 'utf-8'
},
json: result
};
request.post(options, function (err, response, body) {
// do something with your data
})
Let me know if this works.
I've read other posts that have similar 404 errors, my problem is that I can correctly query the JSON data, but can't save without getting this error.
I'm using Angular's $resource to interact with a JSON endpoint. I have the resource object returning from a factory as follows:
app.factory('Product', function($resource) {
return $resource('api/products.json', { id: '#id' });
});
My JSON is valid and I can successfully use resource's query() method to return the objects inside of my directive, like this:
var item = Product.query().$promise.then(function(promise) {
console.log(promise) // successfully returns JSON objects
});
However, when I try to save an item that I've updated, using the save() method, I get a 404 Not Found error.
This is the error that I get:
http://localhost:3000/api/products.json/12-34 404 (Not Found)
I know that my file path is correct, because I can return the items to update the view. Why am I getting this error and how can I save an item?
Here is my data structure:
[
{
"id": "12-34",
"name": "Greece",
"path": "/images/athens.png",
"description": ""
},
...
]
By default the $save method use the POST verb, you will need to figure out which HTTP verbs are accepted by your server en order to make an update, most modern api servers accept PATCH or PUT requests for updating data rather than POST.
Then configure your $resource instance to use the proper verb like this :
app.factory('Product', function($resource) {
return $resource('api/products.json', { id: '#id' }, {'update': { method:'PUT' }});
});
check $resource docs for more info.
NOTE: $resource is meant to connect a frontend with a backend server supporting RESTful protocol, unless you are using one to receive data & save it into a file rather than a db.
Otherwise if you are only working with frontend solution where you need to implement $resource and have no server for the moment, then use a fake one, there is many great solutions out there like deployd.
You probably don't implement POST method for urls like /api/products.json/12-34. POST method is requested from angular for saving a new resource. So you need to update your server side application to support it and do the actual saving.
app.factory('Product', function($resource) {
return $resource('api/products.json/:id', { id: '#id' });
});
Try adding "/:id" at the end of the URL string.