Graphql post body "Must provide query string." - express

I use Express-graphql middleware.
I send the following request in the body line:
POST /graphql HTTP/1.1
Host: local:8083
Content-Type: application/graphql
Cache-Control: no-cache
Postman-Token: d71a7ea9-5502-d5fe-2e36-0ae49c635a29
{
testing {
pass(id: 1) {
idn
}
}
}
and have error
{
"errors": [
{
"message": "Must provide query string."
}
]
}
in graphql i can send update in URL.
URL string is too short. i must send update model like
mutation {
update(id: 2, x1: "zazaza", x2: "zazaza", x3: "zazaza" ...(more more fields)...) {
idn
}
}
I think its must be in request body. How can I send 'update' query or that I'm doing wrong?

Post request needs to manage headers info.
Using Http client - Content-Type: application/json
Using Postman client - Content-Type: application/graphql
but request body looks like string
{"query":"mutation{update(id:1,x1:\"zazaz\",x2:\"zazaz\"......){id x1 x2}}"}

If you are using graphql and want to test it using postman or any other Rest client do this.
In postman, select POST method and enter your URL and set Content-Type as application/graphql then pass your query in the body.
Example:
http://localhost:8080/graphql
Mehtod: POST
Content-Type: application/graphql
Body:
query{
FindAllGames{
_id
title
company
price
year
url
}
}
Thats it you will get the response.

Using Postman Version 7.2.2 I had a similar issue. This version of Postman supports Graphql out of the box. Changing the Content-type to application/json fixed it for me.

for me worked like as following:
In the body
In the Headers
Don't forget mark GraphQl [x] on Body settings
And how was quoted before changes the verb to POST.

This generally occurs when your 'express-graphql' doest receive any params. You need to added a json/applicaton parser in your application.
npm install body-parser
eg -
const bodyParser = require('body-parser');
app.use(bodyParser.json()); // application/json

go to the relevant web page and open "inspect" (by write click ->
inspect || Ctrl+Shift+I in chrome)
go to the network tab and copy the cURL command
open the postman ,then import -> raw text
paste the copied command
then,continue ->

Switch content type to JSON.
Like this

Check if you are using correct protocol in your Postman requests.
I used HTTP instead of HTTPS and this caused the same error.
Changes of content-type, raw or json instead of graphql type didn't help.

Related

"FAILED Incorrect protocol version (missing clientID/version/username)", LastFM API

So, I'm trying to add scrobbles to my LastFM account by using their API. I managed to do the Auth and GET methods, but when trying to use the "track.scrobble" method by using this setup (The words in the curly Brackets get obviously replaced before sending the request):
URL: http://ws.audioscrobbler.com/2.0/?method=track.scrobble&api_key={YOUR_API_KEY}&sk={SESSION_KEY}&api_sig{API_SIGNATURE}&user={USERNAME}
Headers: Content-Type: application/x-www-form-urlencoded
Body: "artist=Kanye+West&timestamp={TIMESTAMP}&track=Heartless"
Method = POST
I get an OK Response (200), but an error from LastFm:
FAILED Incorrect protocol version (missing clientID/version/username)
I'm sorry if this is a stupid question, but I'm very inexperienced working with APIs.
Any help is appreciated!!
EDIT:
The HTTP Request Itself:
var body = "method=track.scrobble&api_key={YOUR_API_KEY}&sk={SESSION_KEY}&api_sig{API_SIGNATURE}&artist=Daniel+Caesar&timestamp={TIMESTAMP}&track=Pseudo".format(
{
"YOUR_API_KEY" : APIKey,
"SESSION_KEY" : session_key,
"TIMESTAMP" : str(OS.get_unix_time() - 31),
"API_SIGNATURE" : ConstructMD5Hash()
}
)
HTTP.request(
url,
headers,
true,
HTTPClient.METHOD_POST,
body
)
HTTP.connect("request_completed",self,"replace_tag")
The ConstructMD5Hash for the API_SIGNATURE:
func ConstructMD5Hash() -> String:
return LastFM_MD5_Hash_Template.format(
{
"YOUR_API_KEY" : APIKey,
"REQUEST_TOKEN" : request_token,
"MY_SECRET" : APISecret,
}
).md5_text()
The Full Response by LAST.FM:
[Server: openresty/1.13.6.2, Date: Mon, 30 Jan 2023 17:10:21 GMT, Content-Type: text/plain; charset=utf-8, Transfer-Encoding: chunked, Access-Control-Allow-Methods: POST, GET, OPTIONS, Access-Control-Allow-Origin: *, Access-Control-Max-Age: 86400, Via: 1.1 google]
FAILED Incorrect protocol version (missing clientID/version/username)
Btw I am using Godot 3.5.1, if that's of any use
Looks like Last.FM generates this error if body lacks required parameters.
In your case URL should be "http://ws.audioscrobbler.com/2.0/" only (this is POST method).
And Body should be:
"method=track.scrobble&api_key={YOUR_API_KEY}&sk={SESSION_KEY}&api_sig{API_SIGNATURE}artist=Kanye+West&timestamp={TIMESTAMP}&track=Heartless"

CORS blocking requests in Kotlin lambda but not in identically setup Node lambda

I have a lambda, written in Kotlin with Serverless and CORS just is not working. I feel like I've tried everything. I deployed a Node Lambda with identical sls.sh command and yaml files. The function looks like this
hello:
handler: handler.hello
events:
- http:
path: hello
method: post
cors: true
My responses look like this in both Node and Kotlin:
{
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*"
},
"body": "{\"id\": \"f9f76590-xxxx-xxxx-xxxx-9c8e99238f40\"}"
}
In the Node case this all works great. I make a fetch call like this and it works (omitted the Promise resolutions for brevity):
var makeRequest = function (data) {
fetch('https://{lambda URL}/hello', {
'headers': {
'content-type': 'application/json'
},
'body': JSON.stringify({ data }),
'method': 'POST'
})
}
In the Kotlin case I get this CORS error back
Access to fetch at 'https://{lambda URL}/hello' from origin
'http://127.0.0.1:8080' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
I try to "enable CORS" in the API Gateway panel but I get that it's already enabled:
And hit submit I get the error (invalid response status code)
When I hover over the error icon it says "Invalid Response status code specified".
Under Gateway Responses, under every sub item (Default 4XX, Default 5XXX, etc) there are response headers set. This is the same across my Node and Kotlin lambdas.
I'm completely out of ideas at this point.
The only potentially odd thing is I am noticing that in my Node request I see access-control-allow-origin: * in response headers in the browser network panel but in the Kotlin one I don't see it.
From this:
I can see that you haven't created Integration Response in your post method.
Try these configurations:
I discovered my CORS issue was because of server errors. If your server has an error and the API Gateway can't get a response then you get a CORS error because the Gateway itself doesn't have the CORS headers.
While the fix is easy (just handle that server error) it was hard to uncover. I wish this was documented better somewhere so hopefully this is found for others :)
For my case specifically, and why it didn't show up in Node but showed up in Kotlin, was because of types. the browser was sending a type Node automatically corrected the type (number to string) but Kotlin was expecting the type and threw a type error.

NodeRED http-response node: How to stop NodeRED adding charset to content-type?

I need to build a http proxy for a jpeg image inside NodeRED. My goal is that the browser does get all page resources in the dashboard from the NodeRED server. And the image is only available from another server.
I tried this abstract flow:
http-in -> http-request -> function node -> http response
In the function node I set the headers:
msg.headers = {
"content-type": "image/jpeg",
"content-disposition": "inline; filename=\"myimage.jpg\""
}
The problem is, that the browser gets these headers (excerpt):
content-type: image/jpeg; charset=utf-8
content-disposition: inline; filename="myimage.jpg"
Where the hell is charset=utf-8 coming from and how to stop NodeRED adding this?
You do not mention what msg.payload is set to in your flow.
If the msg.payload you pass to the HTTP Response node is a String, the content type gets the charset parameter added. This isn't deliberate behaviour of Node-RED - but something happening in the underlying http/express framework.
If msg.payload is a Buffer object, then no such parameter is added.
charset=utf-8, is added by node-red to define the standard there will be no issue if headers added charset on it.

Webhook call failed. Error: Failed to parse webhook JSON response: Expect message object but got: [Chinese letters]

I'm building my own WebhookClient for dialog flow. My code is the following (using Azure Functions, similar to Firebase Functions):
module.exports = async function(context, req) {
const agent = new WebhookClient({ request: context.req, response: context.res });
function welcome(agent) {
agent.add(`Welcome to my agent!!`);
}
let intentMap = new Map();
intentMap.set("Look up person", welcome);
agent.handleRequest(intentMap);
}
I tested the query and the response payload looks like this:
{
"fulfillmentText": "Welcome to my agent!!",
"outputContexts": []
}
And the headers in the response look like this:
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Tue, 11 Dec 2018 18:16:06 GMT
But when I test my bot in dialog flow, it returns the following:
Webhook call failed. Error: Failed to parse webhook JSON response:
Expect message object but got:
"笀ഀ਀  ∀昀甀氀昀椀氀氀洀攀渀琀吀攀砀琀∀㨀 ∀圀攀氀挀漀洀攀 琀漀 洀礀 愀最攀渀琀℀℀∀Ⰰഀ਀  ∀漀甀琀瀀甀琀䌀漀渀琀攀砀琀猀∀㨀 嬀崀ഀ਀紀".
There's Chinese symbols!? Here's a video of me testing it out in DialogFlow: https://imgur.com/yzcj0Kw
I know this should be a comment (as it isn't really an answer), but it's fairly verbose and I didn't want it to get lost in the noise.
I have the same problem using WebAPI on a local machine (using ngrok to tunnel back to Kestrel). A friend of mine has working code (he's hosting in AWS rather than Azure), so I started examining the differences between our responses. I've notice the following:
This occurs with Azure Functions and WebAPI (so it's not that)
The JSON payloads are identical (so it's not that)
Working payload isn't chunked
Working payload doesn't have a content type
As an experiment, I added this code to Startup.cs, in the Configure method:
app.Use(async (context, next) =>
{
var original = context.Response.Body;
var memory = new MemoryStream();
context.Response.Body = memory;
await next();
memory.Seek(0, SeekOrigin.Begin);
if (!context.Response.Headers.ContentLength.HasValue)
{
context.Response.Headers.ContentLength = memory.Length;
context.Response.ContentType = null;
}
await memory.CopyToAsync(original);
});
This code disables response chunking, which is now causing a new and slightly more interesting error for me in the google console:
*Webhook call failed. Error: Failed to parse webhook JSON response: com.google.gson.stream.MalformedJsonException: Unterminated object at line 1 column 94 path $.\u0000\\"\u0000f\u0000u\u0000l\u0000f\u0000i\u0000l\u0000l\u0000m\u0000e\u0000n\u0000t\u0000M\u0000e\u0000s\u0000s\u0000a\u0000g\u0000e\u0000s\u0000\\"\u0000.\
I thought this could be encoding at first, so I stashed my JSON as a string and used the various Encoding classes to convert between them, to no avail.
I fired up Postman and called my endpoint (using the same payload as Google) and I can see the whole response payload correctly - it's almost as if Google's end is terminating the stream part-way through reading...
Hopefully, this additional information will help us figure out what's going on!
Update
After some more digging and various server/lambda configs, I spotted this post here: https://github.com/googleapis/google-cloud-dotnet/issues/2258
It turns out that json.net IS the culprit! I guess it's something to do with the formatters on the way out of the pipeline. In order to prove this, I added this hard-coded response to my POST controller and it worked! :)
return new ContentResult()
{
Content = "{\"fulfillmentText\": null,\"fulfillmentMessages\": [],\"source\": null,\"payload\": {\"google\": {\"expectUserResponse\": false,\"userStorage\": null,\"richResponse\": {\"items\": [{\"simpleResponse\": {\"textToSpeech\": \"Why hello there\",\"ssml\": null,\"displayText\": \"Why hello there\"}}],\"suggestions\": null,\"linkOutSuggestion\": null}}}}",
ContentType = "application/json",
StatusCode = 200
};
Despite the HTTP header saying the charset is utf-8, that is definitely using the utf-16le character set, and then the receiving side is treating them as utf-16be. Given you're running on Azure, it sounds like there is some configuration you need to make in Azure Functions to represent the output as UTF-8 instead of using UTF-16 strings.

BadRequest when try Create folder via REST

I've downloaded a exampled that show the files in the "Shared with everyone" folder in my OneDrive for Bussiness. It's work fine!
But, when I try to create a Folder or File (without content) like this documentation the response became with a BadRequest .
The request goes like:
string requestUrl = String.Format(CultureInfo.InvariantCulture, "{0}/files", serviceInfo.ApiEndpoint);
// Prepare the HTTP request:
using (HttpClient client = new HttpClient())
{
Func<HttpRequestMessage> requestCreator = () =>
{
HttpRequestMessage request = new HttpRequestMessage( HttpMethod.Post, requestUrl);
request.Headers.Add("Accept", "application/json;odata.metadata=full");
request.Content = new StringContent(#"{'__metadata':{'type':'MS.FileServices.Folder'},Name:'TestFolder'}");
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return request;
};
}
And the response is a BadRequest.
I think that my problem is in the "__metadata"'s json value. It´s is correct? Where can I find a working example implementing this operations?
Thanks in advance!
EDIT: Changing the API Endpoint from "/_api/web/getfolderbyserverrelativeurl('Documents')/files" to "_api/files" the error became to: "The property '__metadata' does not exist on type 'MS.FileServices.FileSystemItem'. Make sure to only use property names that are defined by the type."
I´m think I foward in this. But, I still continue with problems.
I am not sure if this can be of any help to you, as this pertains to oneDrive and not oneDrive for business.
Also the documentations are confusing :)
according to the documentation the request should be as follow:
POST https://apis.live.net/v5.0/me/skydrive
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"name": "My example folder"
}
if you can see that in the header there is authorization access token
I don't see that you sent to the server any access token. and that is why you had a bad request.
I am trying to below way to create a folder in SP and it's working for me. Hope it will work for you as well.
Create a folder using SharePoint Web API -
POST https://<Domain>.sharepoint.com/_api/web/folders
Accept: "application/json;odata=verbose"
Content-Type: "application/json"
{
"ServerRelativeUrl": "/Shared Documents/<Folder-Name>"
}