Getting Started with GraphQL
Installing the Tailcall CLI
You can install the latest version - by using NPM.
NPM
-
If you don't already have nodejs installed, you can find the instructions here.
-
Install Tailcall by running the following command in your terminal:
npm i -g @tailcallhq/tailcall
-
To verify the correct installation of Tailcall, run:
tailcall
noteDo not use the
--force
flag during npm installations, as it ignores installing platform-specific builds.
Yarn
-
Install Tailcall by running the following command in your terminal:
yarn global add @tailcallhq/tailcall
-
To verify the correct installation of Tailcall, run:
tailcall
Homebrew
-
If you don't already have Homebrew installed, you can find the instructions here.
-
Add the Tailcall repository to Homebrew by running the following command in your terminal:
brew tap tailcallhq/tailcall
brew install tailcall -
To verify the correct installation of Tailcall, run:
tailcall
-
After completing the installation, perform upgrades with:
brew update
brew upgrade tailcall
Curl
Follow the steps below to manually install the cli on your system:
curl -sSL https://tailcall.run/install.sh | bash -s --
This command fetches and executes the Tailcall installation script. The ~/.tailcall
directory contains the installed files.
Upon completion of the installation, extend your PATH
environment variable to include the ~/.tailcall/bin
directory:
# export PATH=$PATH:~/.tailcall/bin
Docker
To install Tailcall with Docker, follow the steps below. Please note that currently, this installation method only works on Linux/amd64 systems. Before starting, make sure you have Docker installed on your system. If not, download it from here.
-
Pull the latest Tailcall Docker image using the following command:
docker pull tailcall.docker.scarf.sh/tailcallhq/tailcall/tc-server:
This command fetches the latest version of the Tailcall Docker image from the Docker registry.
-
Run the Tailcall Docker container with the following command:
docker run -d --name graphql-server -p 8000:8000 \ -v /path/to/your/configs:/etc/tailcall \ --entrypoint "/bin/sh" \ ghcr.io/tailcallhq/tailcall/tc-server: \ -c "export PATH=$PATH:~/.tailcall/bin && tailcall start /etc/tailcall/config.graphql"
This command launches the GraphQL server in a Docker container, exposing the GraphQL endpoint on port 8080.
Initializing a GraphQL project
Once you have installed the Tailcall binaries, you can simply use the init command to initialize your GraphQL project.
tailcall init <directory>
The command will ask you a few questions and based on your input bootstrap a new GraphQL project with a few files:
.tailcallrc.schema.json
: Provides autocomplete in your editor when the configuration is written injson
oryml
format..graphqlrc.yml
: An IDE configuration that references your GraphQL configuration (if it's in.graphql
format) and the following.tailcallrc.graphql
..tailcallrc.graphql
: Contains Tailcall specific auto-completions for.graphql
format.main.graphql
: This is your root configuration that contains
Writing a GraphQL Configuration
For our first example, we are going to compose a GraphQL schema from the REST APIs at https://jsonplaceholder.typicode.com, a free online REST API with some fake data.
We will use the API at /users
to get a list of users, and /users/:id/posts
to get the posts for each user, and compose them into a single GraphQL schema.
We can use the following formats to define our GraphQL schema: .graphql
, .yml
, .json
.
Create one of the following files and paste the contents into it.
- graphql
- yml
- json
schema
# Specify server configuration: Start GraphQL server at 0.0.0.0:8000
@server(port: 8000) {
query: Query
}
type Query {
# Specify the http path for the users query
users: [User] @http(url: "http://jsonplaceholder.typicode.com/users")
}
# Create a user type with the fields returned by the users api
type User {
id: Int!
name: String!
username: String!
email: String!
# Extend the user type with the posts field
# Use the current user's id to construct the path
posts: [Post] @http(url: "http://jsonplaceholder.typicode.com/users/{{.value.id}}/posts")
}
# Create a post type with the fields returned by the posts api
type Post {
id: Int!
title: String!
body: String!
}
server:
port: 8000
queryValidation: false
hostname: "0.0.0.0"
upstream:
httpCache: 42
schema:
query: Query
types:
Post:
fields:
body:
type:
name: String
required: true
id:
type:
name: Int
required: true
title:
type:
name: String
required: true
user:
type:
name: User
userId:
type:
name: Int
required: true
cache: null
Query:
fields:
posts:
type:
list:
name: Post
http:
url: http://jsonplaceholder.typicode.com/posts
User:
fields:
email:
type:
name: String
required: true
id:
type:
name: Int
required: true
name:
type:
name: String
required: true
phone:
type:
name: String
username:
type:
name: String
required: true
website:
type:
name: String
{
"server": {
"port": 8000,
"queryValidation": false,
"hostname": "0.0.0.0"
},
"upstream": {
"httpCache": 42
},
"schema": {
"query": "Query"
},
"types": {
"Post": {
"fields": {
"body": {
"type": {
"name": "String",
"required": true
}
},
"id": {
"type": {
"name": "Int",
"required": true
}
},
"title": {
"type": {
"name": "String",
"required": true
}
},
"user": {
"type": {
"name": "User"
},
"http": {
"url": "http://jsonplaceholder.typicode.com/users/{{.value.userId}}"
}
},
"userId": {
"type": {
"name": "Int",
"required": true
}
}
}
},
"Query": {
"fields": {
"posts": {
"type": {
"list": {
"name": "Post"
}
},
"http": {
"url": "http://jsonplaceholder.typicode.com/posts"
}
}
}
},
"User": {
"fields": {
"email": {
"type": {
"name": "String",
"required": true
}
},
"id": {
"type": {
"name": "Int",
"required": true
}
},
"name": {
"type": {
"name": "String",
"required": true
}
},
"phone": {
"type": {
"name": "String"
}
},
"username": {
"type": {
"name": "String",
"required": true
}
},
"website": {
"type": {
"name": "String"
}
}
}
}
}
}
The above file is a standard .graphQL
file, with some minor additions such as @upstream
and @http
directives. Basically we specify the GraphQL schema and how to resolve that GraphQL schema in the same file, without having to write any code!
Starting the GraphQL server
Now, run the following command to start the server with the full path to the file that you created earlier.
- graphql
- yml
- json
tailcall start ./jsonplaceholder.graphql
tailcall start ./jsonplaceholder.yml
tailcall start ./jsonplaceholder.json
If the command succeeds, you should see logs like the following below.
INFO File read: ./jsonplaceholder.graphql ... ok
INFO N + 1 detected: 0
INFO 🚀 Tailcall launched at [0.0.0.0:8000] over HTTP/1.1
INFO 🌍 Playground: https://tailcall.run/playground/?u=http://127.0.0.1:8000/graphql
The server starts with the schema provided and prints out a load of meta information. We will cover those in detail in a bit. For now, open the playground URL in a new tab in your browser and try it out for yourself!
Making GraphQL requests to the server
-
Open a web browser and go to https://tailcall.run/playground/?u=http://127.0.0.1:8000/graphql. This should load the GraphiQL interface.
-
In the query editor of GraphiQL, enter the following query
query {
users {
id
name
posts {
title
}
}
} -
After running the query in GraphiQL, expect to see a JSON response structured like this:
{
"data": {
"users": [
{
"id": 1,
"name": "Leanne Graham",
"posts": [
{
"title": "sunt aut facere repellat provident occaecati excepturi option reprehenderit"
}
// Posts truncated for brevity
]
},
{
"id": 2,
"name": "Ervin Howell",
"posts": [
{
"title": "et ea vero quia laudantium autem"
},
{
"title": "in quibusdam tempore odit est dolorem"
}
// Posts truncated for brevity
]
}
// Users truncated for brevity
]
}
}
Deploying GraphQL on Production
Now that you have a running GraphQL server, you can follow our Github Actions Guide to deploy the application on one of the following cloud providers.