Optional variables in the graphql API


I’m trying to get the mapping of an graphql endpoint to an external REST API working. The most parts work so far, only the optional variables do not work and I could not figure out why.

The test configuration for the gateway looks like this:

    "cache_options": {
        "cache_timeout": 10,
        "enable_cache": false,
        "cache_all_safe_requests": false,
        "enable_upstream_cache_control": false,
        "cache_by_headers": [],
        "cache_response_codes": [
    "enable_detailed_recording": true,
    "name": "My GraphQL API",
    "api_id": "my-graphql-api",
    "org_id": "my-org-id",
    "use_keyless": true,
    "version_data": {
        "not_versioned": false,
        "default_version": "Default",
        "versions": {
            "Default": {
                "name": "Default",
                "expires": "3000-01-02 15:04",
                "use_extended_paths": true
    "proxy": {
        "listen_path": "/my-graphql-api/",
        "target_url": "",
        "strip_listen_path": true
    "graphql": {
        "enabled": true,
        "execution_mode": "executionEngine",
        "schema": "type Post { userId: Int id: Int title: String body: String } type Comment { postId: Int id: Int name: String email: String body: String } type Album { userId: Int id: Int title: String } type Photo { albumId: Int id: Int title: String url: String thumbnailUrl: String } type Todo { userId: Int id: Int title: String completed: Boolean } type User { id: Int name: String username: String email: String address: Address phone: String website: String company: Company } type Address { street: String suite: String city: String zipcode: String geo: Geo } type Geo { lat: String lng: String } type Company { name: String catchPhrase: String bs: String } type Query { posts(userId:Int): [Post] comments(postId:Int): [Comment] albums(userId:Int): [Album] photos(albumId:Int): [Photo] todos(userId:Int): [Todo] users(id:Int): [User] }",
        "type_field_configurations": [
                "type_name": "Query",
                "field_name": "posts",
                "mapping": {
                    "disabled": false,
                    "path": "",
                    "url_rewrites": [
                            "match_pattern": "/posts(\\?.*)?",
                            "rewrite_to": "/posts/{{ .arguments.userId }}$1"
                "data_source": {
                    "kind": "HTTPJSONDataSource",
                    "data_source_config": {
                        "url": "https://jsonplaceholder.typicode.com/posts",	
                        "method": "GET"

The post API returns the posts like it should when the query {posts{userId}} is used.

The problem is when an optional variable is defined it does not return anything eg {posts(userId:1){userId}} and the URL is not adjusted.

What is needed that the URL gets adapted when the userId is set?

Hey @lexermal
I noticed 2 things with your API definition:

  • You are using the “old” way of connecting data sources. In Tyk 3.2 the Tyk API definition has changed a bit. Are you using some older version of Tyk?
  • You are trying to do a URL rewrite on the data source directly, in UDG. That will not work. You’d have to proxy your REST as you usually would, just create it as a separate API in Tyk. Do your URL rewrites on the REST API and then use that API as a data source.

I’ll prepare an example for you tomorrow, if you don’t mind waiting.