GraphQL Query with multiple strings via 1 parameter

Hi there!

I am tryting to create a GraphQL query which is handling 1 parameter containing one or more string value(s).
In the schema it looks like this:

type Query {
  products(pcodes: [String!]!): [Product!]!
}

In order to handle this, I have written a function like this:

function TQuery.Products(pcodes: array of String): TArray<TProduct>;
begin
  [...]
end;

I have also tried

function TQuery.Products(pcodes: TArray<String>): TArray<TProduct>;

but whatever I do, I get an error message like Project Project1.exe raised exception class EInvalidCast with message 'Invalid class typecast'.

Any suggestions?

Thanks for your reply.

Stefan

Can you please provide the full code of the project? How are you registering such method in the GraphQL schema?

As a starting point, I have used the Bookshelf demo. From there I have altered my own code...

This is the model I am using:

type Product {
  id: Int!
  code: String!
  price: Float!
}

type ProductsOutput {
  products: [Product]
}

type Query {
  product(code: String!): Product
  products(codes: [String!]!): [Product!]!
}

And this is the unit in which the implementation of the functions is done:

unit GraphQL.StefansTest;

interface

uses
  Generics.Collections, GraphQL.Main, GraphQL.Schema, FireDAC.Comp.Client,
  FireDAC.Stan.Error, FireDAC.Stan.Param, System.SysUtils, System.StrUtils;

type
  TProduct = class
  private
    FId: Integer;
    FCode: String;
    FPrice: Double;
  public
    constructor Create(AId: Integer; ACode: String; APrice: Double);
    property Id: Integer read FId;
    property Code: String read FCode;
    property Price: Double read FPrice;
  end;

  TQuery = class
  public
    function Product(Code: String): TProduct;
    function Products(const Codes: TArray<string>): TArray<TProduct>;
  end;

implementation

uses
  DataConnModule;

var
  ProductList: TObjectList<TProduct>;

{ TProduct }

constructor TProduct.Create(AId: Integer; ACode: String; APrice: Double);
begin
  inherited Create;

  FId := AId;
  FCode := ACode;
  FPrice := APrice;
end;

{ TQuery }

function TQuery.Product(Code: String): TProduct;
var
  qWork: TFDQuery;
begin
  qWork := TFDQuery.Create(nil);
  qWork.Connection := dmDataConn.DBConn;

  with qWork do
  begin
    Close;
    SQL.Clear;
    SQL.Add('select top 1 ' +
            '       ID, ' +
            '       InternalNumber, ' +
            '       SellingPrice ' +
            'from Products ' +
            'where ID = ' + Code + ' ' +
            'order by ID desc ');
    Open;
    FetchAll;
  end;

  if qWork.RecordCount = 0 then
    Result := nil
  else
    Result := TProduct.Create(qWork.FieldByName('ID').AsInteger,
                              qWork.FieldByName('ID').AsString,
                              qWork.FieldByName('SellingPrice').AsFloat);

  qWork.Close;
  qWork.Free;
end;

function TQuery.Products(const Codes: TArray<string>): TArray<TProduct>;
var
  qWork: TFDQuery;
  tmpLine: String;
  i: Integer;
begin
  {
     to be completed
  }
  Result := ProductList.ToArray;
end;

initialization
  ProductList := TObjectList<TProduct>.Create(True);

finalization
  ProductList.Free;

end.

When I run a Product query (including parameter with 1 value only) it is working fine. However, when I run a Products query (including parameter with multiple values) the following error raises:
Project Project1.exe raised exception class EInvalidCast with message 'Invalid class typecast'.

Hopefully this is something that can be solved easily?
Thanks for helping.

Regards,
Stefan

To receive array values, item type should be TValue. So you should use it like this:

function TQuery.Products(pcodes: TArray<TValue>): TArray<TProduct>;

Thanks!
It's working perfect now.

1 Like

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