Skip to main content

Working with Queries & Mutations

You can directly edit your project schema to add queries and mutations that work with connected services or objects inside of TakeShape.

You can edit the schema in your browser using the built-in editor. Or, you can export your schema, edit it in your favorite code editor, and reimport it. Learn more about editing your schema.

Queries and mutations have the same structure, with the same required fields. They use separate keys in the schema file: queries and mutations, respectively.

Edit an existing query or mutation#

From the Schema tab, you can browse a list of the queries and mutations in your project. Click the Edit button for any one to edit the snippet of schema for that particular query or mutation.

From here, you can customize the query or mutation to add new resolvers, update the shape of the arguements or response, and more.

Add a new query or mutation#

To add a new query or mutation to your schema, you can provide a new entry to the "queries" or "mutations" objects.

To add a new query or mutation to your schema, you can provide a new entry to the "queries" or "mutations" objects with the following properties:

  • shape: string (required) Specifies which shape is returned by the query or mutation. The shape can refer to a shape in the schema's "shapes" object or a shape that's available on a service schema (we provide an example of a remote shape reference below).
  • resolver: object (required) Configures the resolver for your query or mutation. Learn more about resolvers
  • description: string (optional) Provides more detail about what the query or mutation is for. This will be displayed in the automatically-generated GraphQL API docs (optional)
  • args: string (optional) The args field specifies the name of a Shape for the input arguments required by your resolver. If your query does not need any input, you can omit this.

Example: TakeShape Query#

Here, we're creating a custom query for an existing shape, using the built in takeshape:list resolver:

"getPostById": {
"shape": "Post",
"resolver": {
"name": "takeshape:get",
"service": "takeshape:local",
"options": {
"model": "Post"
}
},
"description": "Get a Post by ID",
"args": "TSGetArgs<Post>"
}

Here, the shape of the query args is a built-in template provided by TakeShape. The generic  TSGetArgs template type generates the arguments expected by the takeshape:get resolver, using the Post shape as its input.

Example: Rick and Morty GraphQL service#

Here, we're using a connection to the Rick & Morty GraphQL API to define a query that fetches a list of all the characters in the show, using types that exist on the Rick and Morty API:

"getRickAndMortyCharacters": {
"shape": "graphql:rick-and-morty:Characters",
"description": "Get the list of all characters",
"resolver": {
"name": "graphql:query",
"service": "graphql:rick-and-morty",
"options": {
"fieldName": "characters"
}
}
"args": {
"type": "object",
"properties": {
"page": {
"type": "integer"
},
"filter": {
"@ref": "graphql:rick-and-morty:FilterCharacter"
}
}
}
}

When defining the query, we set the resolver to graphql:query, which accesses the API provided by the graphql:rick-and-morty service defined in the services object of the schema. We define the query's args as an object to provide the expected arguments for pagination.

In the resolver options, we set the fieldName value to the name of Rick and Morty GraphQL query characters. By doing this, we're configuring the getRickAndMortyCharacters query in our GraphQL API as a wrapper around the query provided by the Rick and Morty GraphQL API.

We're also able to reference the GraphQL Types on the Rick and Morty API with the graphql:service:type syntax. For the shape property, this allows us to define our query's return value without adding a new Shape to our schema. For the filter arg, this allows us to reference to the remote FilterCharacter argument type that the character query we're wrapping expects.

Learn more about References

Example: Open Weather REST service query#

Here's one more example showing how to add a query to your TakeShape project that can fetch current weather conditions for a zip code from the Open Weather API. When we're done, we'll have this query available on our project:

query($zip: String!) {
getWeather(zip: $zip) {
name
main {
temp
temp_min
temp_max
feels_like
}
}
}

Authoring queries for REST services takes more work than for GraphQL services, since we need to explicitly define the shapes used by the service and make sure they match the data structure of the REST responses.

Add the Query#

After connecting the Open Weather service and exporting your project schema to a schema.json file, we'll open the file in our favorite code editor. To the queries object in schema.json, we'll add:

"getWeather": {
"description": "Returns the weather for a provided location",
"args": "WeatherArgs",
"shape": "Weather",
"resolver": {
"name": "rest:get",
"service": "rest:weather",
"options": {
"path": "weather"
},
"argsMapping": {
"searchParams.zip": [["jsonPath", {"path": "$.args.zip"}]],
"searchParams.units": [["set", {"value": "imperial"}]]
},
}
}

Here, we're creating a query by defining the shapes for the query's input arguments, the shape of the query's response, and the resolver the query will use to fulfill our request.

The resolver describe how the query should be implemented. In this case, we're saying that the resolver should make a GET call to the /weather path of the service we connected in the last step.

In the resolver, we're also defining a mapping between our GraphQL query's input arguments and the arguments the REST endpoint expects. Since we're making a GET request, we'll pass our arguments as query string arguments, also referred to as search params.

Learn more about configuring resolvers

Add the Shapes#

Next, we'll need to add the shapes we reference in the query: WeatherArgs, Weather, and a helper shape WeatherMain. We cover adding these arguments and importing the edited schema in our docs on Adding REST services, shapes, and queries.