Delphi & GraphQL syntax

I am using Delphi 11.2 using TNetHttpClient component
I have manage to connect get my token okay.
I can get the GraphQL query returned in Postman ok.

I am now trying to get a simple query to run as follows:

      Params.Add('query:\' + 'fetchInstalledModules {id }}"');
      NetHTTPClient1.CustomHeaders['Content-Type'] := 'application/json';
      NetHTTPClient1.CustomHeaders['Authorization'] := 'Bearer '+token;
      memoLog.Lines.Text := NetHTTPClient1.Post('http://pbx.safeguardmeathome.com:83/admin/api/api/gql', params).ContentAsString;

I have tried various ‘guesses’ on this line

Params.Add('query:\' + 'fetchInstalledModules {id }}"');//,"variables":{);

I get this returned.

{"errors":[{"message":"GraphQL Request must include at least one of those two parameters: \"query\" or \"queryId\"","status":false}]}

Anyone know how I format the parameter.

GitHub - 2fd/graphdoc: Static page generator for documenting GraphQL Schema

API GraphQL Documentation - PBX GUI - Documentation (freepbx.org)

GraphQL PBX APIs Documentation - PBX GUI - Documentation (freepbx.org)

API GraphQL Explorer - PBX GUI - Documentation (freepbx.org)

Thanks for the reply but I know the query I need eg

query : {fetchInstalledModules {id }}

My issue is whatever syntax I use I get

{"errors":[{"message":"GraphQL Request must include at least one of those two parameters: \"query\" or \"queryId\"","status":false}]}

So I need the correct syntax here

Params.Add('query:\' + 'fetchInstalledModules {id }}"');//,"variables":{);

Cheers

Framework Module GraphQL APIs - PBX GUI - Documentation (freepbx.org)

fetchinstalledmodules is expecting.

query {
fetchInstalledModules {
status
message
modules{
name,
state,
version,
license
}
}
}

If I send this in postman

{fetchInstalledModules {id }}

I get

{
    "data": {
        "fetchInstalledModules": {
            "id": "bW9kdWxlOg=="
        }
    }
}

I am just trying to use the simplest query to get a Jason reply from GraphQL

Delphi Syntax attempts for myQuery (all failed)

      myQuery := '{"query": "{fetchInstalledModules {id }}"}';
      myQuery := 'query:\fetchInstalledModules {id }';
      myQuery := '{"query":"query{fetchInstalledModules{id}}","variables":{}}';
      myQuery := '"query":"query{fetchInstalledModules{id}","variables":{}';

      params.Add(myQuery)   ;
      memo1.Text := params.DelimitedText;
      NetHTTPClient1.CustomHeaders['Content-Type'] := 'application/json';
      NetHTTPClient1.CustomHeaders['Authorization'] := 'Bearer '+token;
      memoLog.Lines.Text := NetHTTPClient1.Post('http://myDomain.com:83/admin/api/api/gql', params).ContentAsString;

I have manage to create a new extension in Postman. So there is an error in the way I am adding the query in Delphi.

Any ideas?

Hi guys,

I have also tried using REST component but even with the simple query is fails with ‘error while decoding to JSON’


procedure TMasterDetailForm.Button9Click(Sender: TObject);
var
GraphQLEndpoint: string;
AuthToken: string;
Query: string;
ResponseJSON: TJSONObject;
RESTClient: TRESTClient;
RESTRequest: TRESTRequest;
ResponseContent: string;
JSONQuery: TJSONObject;
begin
GraphQLEndpoint := 'http://XYZ:83/api/api/gql';
AuthToken := memo1.Text;
Query := '{fetchInstalledModules{id}}';
JSONQuery := TJSONObject.Create;
JSONQuery.AddPair(TJSONPair.Create('query', Query));
// Convert the JSON object to a string
Query := JSONQuery.ToString;
RESTClient := TRESTClient.Create(nil);
RESTRequest := TRESTRequest.Create(nil);
try
// Set the base URL of the GraphQL endpoint
RESTRequest.Client := RESTClient;
RESTClient.BaseURL := GraphQLEndpoint;
// Set the authorization header with the bearer token
RESTRequest.Params.AddItem('Authorization', 'Bearer ' + Memo1.Text, TRESTRequestParameterKind.pkHTTPHEADER);
// Set the content type header for GraphQL
RESTRequest.Params.AddItem('Content-Type', 'application/json', TRESTRequestParameterKind.pkHTTPHEADER);
// Build the request body as a JSON string
RESTRequest.Body.Add(Query);
// Send the query to the GraphQL endpoint
RESTRequest.Method := TRESTRequestMethod.rmPOST;
RESTRequest.Execute;
// Get the response content as a string
ResponseContent := RESTRequest.Response.Content;
// Parse the response JSON
ResponseJSON := TJSONObject.ParseJSONValue(ResponseContent) as TJSONObject;
memo4.Text := ResponseJSON.ToString;
// Handle the response JSON as needed
// ...
finally
RESTRequest.Free;
RESTClient.Free;
end;
end;

It’s obviously a JSON decoding problem but where ???

Maybe you can try this. My code is in C#. I’m sure you can convert.

public class FreePBXExtensionMutation
{
private readonly IRepository<ApiConfiguration, Guid> _apiConfigurationRepository;
public FreePBXExtensionMutation(IRepository<ApiConfiguration, Guid> apiConfigurationRepository)
{
_apiConfigurationRepository = apiConfigurationRepository;

    }
    public async void AddExtension(long extensionId, string name, string tech, string channelName, string outboundCid, string email, string umGroups, bool umEnable, string umPassword, string vmPassword, bool vmEnable, string callerID, string emergencyCid, string clientMutationId, int maxContacts)
    {
        FreePBXValidateAccessToken freePBXValidateAccessToken = new FreePBXValidateAccessToken(_apiConfigurationRepository);
        GetAPIConfiguration getAPIConfiguration = new GetAPIConfiguration(_apiConfigurationRepository);
        var _apidata = await getAPIConfiguration.GetAPIConfigAsync("GraphQLURL");

        await freePBXValidateAccessToken.TokenValidationService();

        var endPoint = new Uri(_apidata.BaseUrl);
        var graphQLClient = FreePBXGraphQLHttpClient.GetInstance(endPoint);



        var request = new GraphQLRequest
        {
            Query = @"
            mutation ($input: addExtensionInput!) {
                addExtension(input: $input) {
                    status
                    message
                }
            }
        ",
            Variables = new
            {
                input = new
                {
                    extensionId,
                    name,
                    tech,
                    channelName,
                    outboundCid,
                    email,
                    umGroups,
                    umEnable,
                    umPassword,
                    vmPassword,
                    vmEnable,
                    callerID,
                    emergencyCid,
                    clientMutationId,
                    maxContacts
                }
            }
        };
        graphQLClient.HttpClient.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", SharedSession.tokenSession.AccessToken);
        var response = await graphQLClient.HttpClient.SendMutationAsync<Root>(request, cancellationToken: default);

        if (response.Errors != null && response.Errors.Count() > 0)
        {
            //throw new Exception("Error adding extension: " + response.Errors[0].Message);
        }
        else
        {
            //Console.WriteLine("Extension added successfully");
        }
    }

This work well for me in C#

Thanks for the insight. I used ChatGPT to convert to Delphi then to REST. Looking at the code I got it working as follows:

Query := '{fetchInstalledModules{id} }'; 
RESTRequest.Params.AddItem('Authorization', 'Bearer ' + Memo1.Text, TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);

 RESTRequest.AddParameter('query', Query, TRESTRequestParameterKind.pkGETorPOST, [poDoNotEncode]);
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.