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
jsonplaceholder.graphql
schema
# Specify server configuration: Start tailcall server at 0.0.0.0:8000 and enable GraphiQL playground
@server(port: 8000, graphiql: true)
# Specify a base url for all http requests
@upstream(baseURL: "http://jsonplaceholder.typicode.com") {
query: Query
}
type Query {
# Specify the http path for the users query
users: [User] @http(path: "/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(path: "/users/{{value.id}}/posts")
}
# Create a post type with the fields returned by the posts api
type Post {
id: Int!
title: String!
body: String!
}
jsonplaceholder.yml
server:
port: 8000
graphiql: true
queryValidation: false
hostname: "0.0.0.0"
upstream:
baseURL: "http://jsonplaceholder.typicode.com"
httpCache: true
schema:
query: Query
types:
Post:
fields:
body:
type: String
required: true
id:
type: Int
required: true
title:
type: String
required: true
user:
type: User
http:
path: /users/{{value.userId}}
userId:
type: Int
required: true
Query:
fields:
posts:
type: Post
list: true
http:
path: /posts
User:
fields:
email:
type: String
required: true
id:
type: Int
required: true
name:
type: String
required: true
phone:
type: String
username:
type: String
required: true
website:
type: String
jsonplaceholder.json
{
"server": {
"port": 8000,
"graphiql": true,
"queryValidation": false,
"hostname": "0.0.0.0"
},
"upstream": {
"baseURL": "http://jsonplaceholder.typicode.com",
"httpCache": true
},
"schema": {
"query": "Query"
},
"types": {
"Post": {
"fields": {
"body": {
"type": "String",
"required": true
},
"id": {
"type": "Int",
"required": true
},
"title": {
"type": "String",
"required": true
},
"user": {
"type": "User",
"http": {
"path": "/users/{{value.userId}}"
}
},
"userId": {
"type": "Int",
"required": true
}
}
},
"Query": {
"fields": {
"posts": {
"type": "Post",
"list": true,
"http": {
"path": "/posts"
}
}
}
},
"User": {
"fields": {
"email": {
"type": "String",
"required": true
},
"id": {
"type": "Int",
"required": true
},
"name": {
"type": "String",
"required": true
},
"phone": {
"type": "String"
},
"username": {
"type": "String",
"required": true
},
"website": {
"type": "String"
}
}
}
}
}
The above file is a standard .graphQL
file, with a few additions such as @upstream
and @http
directives. So basically we specify the GraphQL schema and how to resolve that GraphQL schema in the same file, without having to write any code!