Search Results for

    Show / Hide Table of Contents

    Getting started

    In this article, we will walk you through the basics of installing GraphQL for Delphi and creating a GraphQL server with it.

    Installation

    You can use GraphQL for Delphi starting in Delphi 10 Seattle and up to the latest Delphi versions. GraphQL for Delphi is distributed and supported by TMS Software.

    You can refer to the Download page to find the links to download installer for GraphQL for Delphi for your specified Delphi version:

    GraphQL for Delphi Download Page

    Installation is pretty straightforward, just download and run the installer.

    GraphQL for Delphi is also available in GetIt. Go to Delphi menu option Tools | GetIt Package Manager... and search for graphql. Select GraphQL for Delphi from the list of available filtered packages and click "Install".

    Creating a Hello World GraphQL server

    Once you have installed GraphQL for Delphi, you can build your first Hello World GraphQL server, using the following tutorial.

    1. Create a new WebBroker-based web application

    • Choose Delphi menu option File -> New -> Other...;
    • Select Delphi -> Web category, and then double click option Web Server Application;
    • Follow the wizard, choosing Stand-alone GUI Application as WebBroker project type and VCL application as application type;
    • Once finished, the wizard will create a project with two units: FormUnit1 and WebModuleUnit1.

    2. Define your GraphQL schema

    • Open data module WebModule1 in unit WebModuleUnit1;
    • Drop the component TGraphQLSchema in the data module.
    • Using object inspector, edit the Definition property and paste the following text:
    type Query {
         hello(name: String!): String
    }
    

    3. Setting up the field resolver

    • Still in the object inspector, double click the OnInitSchema event;
    • Paste the following implementation in the new created event handler:
    procedure TWebModule1.GraphQLSchema1InitSchema(Sender: TObject; Schema: TSchemaDocument);
    begin
      Schema.SetResolver('Query', 'hello', function(Args: TFieldResolverArgs): TValue
        begin
          Result := 'Hello, ' + Args.GetArgument('name').AsString;
        end
      );
    end;
    

    4. Adding the WebBroker dispatcher

    • Drop the component TGraphQLWebBroker​Dispatcher in the data module;
    • Double click the Schema property of the component to associate the dispatcher to the previously added TGraphQLSchema component;
    • Set property Options.PlaygroundEnabled to True.

    5. Running and testing the GraphQL server

    Your GraphQL server is now ready to run.

    • Run the server, and then click the Open Browser function (or simply use your web browser to navigate to url http://localhost:8080.
    • The browser should open the GraphQL Playground IDE. Using the editor at the left side, type the following query:
    query {
      hello(name: "World")
    }
    
    • Click the Play button in the middle of the screen, and you should get the server response at the right editor:
    {
      "data": {
        "hello": "Hello, World"
      }
    }
    

    Congratulations! You have built your first GraphQL server using Delphi!

    Bookshelf server: a more complex example

    Let's create a sample Bookshelf application to put all pieces together.

    1. Create a new Web Server Application using File -> New -> Other... dialog.

    Choose Stand-alone GUI Application as WebBroker project type and VCL application as application type.

    2. Create new unit GraphQL.Bookshelf.pas with resolvers implementation.

    For demo purposes we are not using any database, only simple TList<T> instances. Use the following code as the full unit source code.

        unit GraphQL.Bookshelf;
    
        interface
    
        uses
          Generics.Collections,
          GraphQL.Main,
          GraphQL.Schema;
    
        type
          TBook = class;
    
          TAuthor = class
          private
            FId: Integer;
            FName: string;
            function GetBooks: TArray<TBook>;
          public
            constructor Create(AName: string);
            property Books: TArray<TBook> read GetBooks;
    
            property Id: Integer read FId;
            property Name: string read FName;
          end;
    
          TBook = class
          private
            FId: Integer;
            FName: string;
            FAuthorId: Integer;
            function GetAuthor: TAuthor;
          public
            constructor Create(AName: string; AAuthorID: Integer);
            property Id: Integer read FId;
            property Name: string read FName;
            property Author: TAuthor read GetAuthor;
          end;
    
          TMutation = class
          public
            function CreateAuthor(Name: string): TAuthor;
            function CreateBook(Name: string; AuthorID: Integer): TBook;
          end;
    
          TQuery = class
            function Books: TArray<TBook>;
            function Authors: TArray<TAuthor>;
            Function Book(id: Integer): TBook;
            function Author(id: Integer): TAuthor;
          end;
    
        implementation
    
        var
          Counter: Integer;
          BookList: TObjectList<TBook>;
          AuthorList: TObjectList<TAuthor>;
    
        { TBook }
    
        constructor TBook.Create(AName: string; AAuthorID: Integer);
        begin
          inherited Create;
          FName := AName;
          FAuthorID := AAuthorID;
          FId := Counter;
          Inc(Counter);
        end;
    
        function TBook.GetAuthor: TAuthor;
        var
          I: Integer;
        begin
          Result := nil;
          for I := 0 to AuthorList.Count - 1 do
            if AuthorList[I].Id = Self.FAuthorId then
            begin
              Result := AuthorList[I];
              Break;
            end;
        end;
    
        { TMutation }
    
        function TMutation.CreateAuthor(Name: string): TAuthor;
        begin
          Result := TAuthor.Create(Name);
          try
            AuthorList.Add(Result)
          except
            Result.Free;
            raise;
          end;
        end;
    
        function TMutation.CreateBook(Name: string; AuthorID: Integer): TBook;
        begin
          Result := TBook.Create(Name, AuthorID);
          try
            BookList.Add(Result)
          except
            Result.Free;
            raise;
          end;
        end;
    
        { TAuthor }
    
        constructor TAuthor.Create(AName: string);
        begin
          inherited Create;
          FName := AName;
          FId := Counter;
          Inc(Counter);
        end;
    
        function TAuthor.GetBooks: TArray<TBook>;
        var
          I: Integer;
          Books: TList<TBook>;
        begin
          Books := TList<TBook>.Create;
          try
            for I := 0 to BookList.Count - 1 do
              if BookList[I].FAuthorId = Self.Id then
                Books.Add(BookList[I]);
    
            Result := Books.ToArray;
          finally
            Books.Free;
          end;
        end;
    
        { TQuery }
    
        function TQuery.Author(id: Integer): TAuthor;
        var
          I: Integer;
        begin
          Result := nil;
          for I := 0 to AuthorList.Count - 1 do
            if AuthorList[I].Id = id then
            begin
              Result := AuthorList[I];
              Break;
            end;
        end;
    
        function TQuery.Authors: TArray<TAuthor>;
        begin
          Result := AuthorList.ToArray;
        end;
    
        function TQuery.Book(id: Integer): TBook;
        var
          I: Integer;
        begin
          Result := nil;
          for I := 0 to BookList.Count - 1 do
            if BookList[I].Id = id then
            begin
              Result := BookList[I];
              Break;
            end;
        end;
    
        function TQuery.Books: TArray<TBook>;
        begin
          Result := BookList.ToArray;
        end;
    
        initialization
          Counter := 1;
          BookList := TObjectList<TBook>.Create(True);
          AuthorList := TObjectList<TAuthor>.Create(True);
    
        finalization
          BookList.Free;
          AuthorList.Free;
    
        end.
    

    3. Configure the GraphQL Server application

    • Add GraphQL.Bookshelf to WebModuleUnit1 uses.

    • Open WebModuleUnit1 designer and drop TGraphQLSchema and TGraphQLWebBroker​Dispatcher components there.

    • In GraphQLWebBrokerDispatcher1 properties set Schema to our newly created GraphQLSchema1 and Options.PlaygroundEnabled to True.

    • Copy full GraphQL schema definition into GraphQLSchema1.Definition property:

        type Book {
          id: ID!
          name: String!
          author: Author!
        }
    
        type Author {
          id: ID!
          name: String!
          books: [Book!]!
        }
    
        type Query {
          author(id: ID!): Author 
          book(id: ID!): Book
          books: [Book!]!
          authors: [Author!]!
        }
    
        type Mutation {
          createAuthor(name: String!): Author!
          createBook(name: String!, authorId: ID!): Book!
        } 
    
    • Set bindings between resolvers and GraphQL schema in TGraphQLSchema.OnInitSchema handler:
      procedure TWebModule1.GraphQLSchema1InitSchema(Sender: TObject;
        Schema: TSchemaDocument);
      begin
        Schema.Bind('Query', TQuery);
        Schema.Bind('Mutation', TMutation);
      end;
    

    4. Run and test the server

    Now the GraphQL Server application is ready to use. Start the application, click Start button and open http://localhost:8080/graphql/ in your browser. You should see GraphQL Playground IDE and now you can perform queries to your GraphQL server.

    Here are some query examples you can use:

    # create author, return author id
    mutation {
      createAuthor(name: "Leo") {
        id
      }
    }
    
    # create book, return book and author
    mutation {
      createBook(name: "War and Peace", authorId: 1) {
        id
        author {
          name
        }
      }
    }
    
    # return all books with authors
    query {
      books {
        name
        author {
          id
          name
        }
      }
    }
    
    # get author books using variables
    query GetAuthor($id: ID!) {
      author(id: $id) {
        name 
        books {
          id
          name
        }
      }
    }
    # variables:
    {
      "id": 1
    }
    
    In This Article
    Back to top GraphQL for Delphi v1.4
    © 2021 - 2024 tmssoftware.com