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 optionWeb Server Application
; - Follow the wizard, choosing
Stand-alone GUI Application
as WebBroker project type andVCL application
as application type; - Once finished, the wizard will create a project with two units:
FormUnit1
andWebModuleUnit1
.
2. Define your GraphQL schema
- Open data module
WebModule1
in unitWebModuleUnit1
; - 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 TGraphQLWebBrokerDispatcher 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 urlhttp://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 TGraphQLWebBrokerDispatcher components there.
In
GraphQLWebBrokerDispatcher1
properties setSchema
to our newly createdGraphQLSchema1
andOptions.PlaygroundEnabled
toTrue
.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
}