0
votes

I'm using a website that requires that their API key AND query data be submitted using Webform.Post method. I'm able to get this to work in Python, C# and I'm even able to construct and execute a cURL command which returns a usable JSON file that Excel can parse. I am also using Postman to validate my parameters and everything looks good using all these methods. However, my goal is to build a query form that I can use within Excel but I can't get past this query syntax in PowerBi Query.

For now I am doing a simple query. That query looks like this:

let
    url_1 = "https://api.[SomeWebSite].com/api/v1.0/search/keyword?apiKey=blah-blah-blah",

    Body_1 = {
            
            "SearchByKeywordRequest: 
            
            {
                ""keyword"": ""Hex Nuts"",
                ""records"": 0,
                ""startingRecord"": 0,
                ""searchOptions"": Null.Type,
                ""searchWithYourSignUpLanguage"": Null.Type
            }"
            
             },
    
    Source = WebMethod.Post(url_1,Body_1)
    
in
    Source

ScreenSnip showing valid syntax

It generates the following error:

Expression.Error: We cannot convert the value "POST" to type Function.
Details:
    Value=POST
    Type=[Type]

ScreenSnip of Error as it appears in PowerQuery Advanced Editor

I've spend the better part of the last two days trying to find either some example using this method or documentation. The Microsoft documentation simple states the follow:

WebMethod.Post
04/15/2018
2 minutes to read

About
Specifies the POST method for HTTP.

https://docs.microsoft.com/en-us/powerquery-m/webmethod-post

This is of no help and the only posts I have found so far criticize the poster for not using GET versus POST. I would do this but it is NOT supported by the website I'm using. If someone could just please either point me to a document which explains what I am doing wrong or suggest a solution, I would be grateful.

1

1 Answers

1
votes

WebMethod.Post is not a function. It is a constant text value "POST". You can send POST request with either Web.Contents or WebAction.Request function.

A simple example that posts JSON and receives JSON:

let
    url = "https://example.com/api/v1.0/some-resource-path",
    headers = [#"Content-Type" = "application/json"],
    body = Json.FromValue([Foo = 123]),
    source = Json.Document(Web.Contents(url, [Headers = headers, Content = body])),
    ...

Added Nov 14, 19

Request body needs to be a binary type, and included as Content field of the second parameter of Web.Contents function.

You can construct a binary JSON value using Json.FromValue function. Conversely, you can convert a binary JSON value to a corresponding M type using Json.Document function.

Note {} is list type in M language, which is similar to JSON array. [] is record type, which is similar to JSON object.

With that said, your query should be something like this,

let
    url_1 = "https://api.[SomeWebSite].com/api/v1.0/search/keyword?apiKey=blah-blah-blah",

    Body_1 = Json.FromValue([
        SearchByKeywordRequest = [
            keyword = "Hex Nuts",
            records = 0,
            startingRecord = 0,
            searchOptions = null,
            searchWithYourSignUpLanguage = null
        ]
    ]),

    headers = [#"Content-Type" = "application/json"],

    source = Json.Document(Web.Contents(url_1, [Headers = headers, Content = Body_1])),

    ...