Escape-Technologies / graphman

Quikly scaffold a postman collection for a GraphQL API. Compatible with Postman & Insomnia.
MIT License
242 stars 12 forks source link

Generate mock responses for mutations and queries. #33

Open Gbahdeyboh opened 2 years ago

Gbahdeyboh commented 2 years ago

GraphQL is a very declarative query language. It provides a declarative approach to data fetching. From the schema, you already know what kind of data to expect and you can choose to request just what you need.

We can leverage the declarative nature of GraphQL and generate mock response data that can be included in the generated collection. Having responses pre-generated in a collection means consumers of that collection can create mock servers for that API by just clicking a few buttons without having to worry about populating the collection with sample responses from scratch.

nohehf commented 2 years ago

That's a really cool idea. Anyway this (and some other features) needs a better way to generate mock data, for now, it's really limited.

nohehf commented 2 years ago

Hey @Gbahdeyboh! I developed most of what's needed to have a first simple mock (response example) generation, however as described in #37, I ran into an issue: postman seems to remove the body of my example responses in the generated collection: The generated item by graphman is the following:

{
  "name":"character",
  "request":{
    "method":"POST",
    "header":[

    ],
    "body":{
      "mode":"graphql",
      "graphql":{
        "query":"query character($id: ID!) {\n  character(id: $id) {\n    __typename\n    id # The id of the character.\n    name # The name of the character.\n    status # The status of the character ('Alive', 'Dead' or 'unknown').\n    species # The species of the character.\n    type # The type or subspecies of the character.\n    gender # The gender of the character ('Female', 'Male', 'Genderless' or 'unknown').\n    # origin # The character's origin location\n    # location # The character's last known location\n    image # Link to the character's image. All images are 300x300px and most are medium shots or portraits since they are intended to be used as avatars.\n    # episode # Episodes in which this character appeared. # Type: NON_NULL\n    created # Time at which the character was created in the database.\n  }\n}",
        "variables":"{\n\t\"id\": 1\n}"
      }
    },
    "url":{
      "raw":"https://rickandmortyapi.com/graphql",
      "protocol":"https",
      "host":[
        "rickandmortyapi",
        "com"
      ],
      "path":[
        "graphql"
      ]
    }
  },
  "response":[
    {
      "name":"character",
      "originalRequest":{
        "method":"POST",
        "header":[

        ],
        "body":{
          "mode":"graphql",
          "graphql":{
            "query":"query character($id: ID!) {\n  character(id: $id) {\n    __typename\n    id # The id of the character.\n    name # The name of the character.\n    status # The status of the character ('Alive', 'Dead' or 'unknown').\n    species # The species of the character.\n    type # The type or subspecies of the character.\n    gender # The gender of the character ('Female', 'Male', 'Genderless' or 'unknown').\n    # origin # The character's origin location\n    # location # The character's last known location\n    image # Link to the character's image. All images are 300x300px and most are medium shots or portraits since they are intended to be used as avatars.\n    # episode # Episodes in which this character appeared. # Type: NON_NULL\n    created # Time at which the character was created in the database.\n  }\n}",
            "variables":"{\n\t\"id\": 1\n}"
          }
        },
        "url":{
          "raw":"https://rickandmortyapi.com/graphql",
          "protocol":"https",
          "host":[
            "rickandmortyapi",
            "com"
          ],
          "path":[
            "graphql"
          ]
        }
      },
      "body":"{\n  \"data\": {\n    \"character\": {\n      \"__typename\": \"Character\",\n      \"id\": \"1\",\n      \"name\": \"\",\n      \"status\": \"\",\n      \"species\": \"\",\n      \"type\": \"\",\n      \"gender\": \"\",\n      \"origin\": null,\n      \"location\": null,\n      \"image\": \"\",\n      \"episode\": null,\n      \"created\": \"\"\n    }\n  }\n}",
      "header":[

      ],
      "cookie":[

      ],
      "_postman_previewlanguage":"json"
    }
  ]
}

However, when importing in postman the example request body is empty: image

I checked if this is an issue coming from graphman generated item, but if I create an example from an actual response in Postman and export the collection, I get the following item:

{
  "name":"character",
  "request":{
    "method":"POST",
    "header":[

    ],
    "body":{
      "mode":"graphql",
      "graphql":{
        "query":"query character($id: ID!) {\n  character(id: $id) {\n    __typename\n    id # The id of the character.\n    name # The name of the character.\n    status # The status of the character ('Alive', 'Dead' or 'unknown').\n    species # The species of the character.\n    type # The type or subspecies of the character.\n    gender # The gender of the character ('Female', 'Male', 'Genderless' or 'unknown').\n    # origin # The character's origin location\n    # location # The character's last known location\n    image # Link to the character's image. All images are 300x300px and most are medium shots or portraits since they are intended to be used as avatars.\n    # episode # Episodes in which this character appeared. # Type: NON_NULL\n    created # Time at which the character was created in the database.\n  }\n}",
        "variables":"{\n\t\"id\": 1\n}"
      }
    },
    "url":{
      "raw":"https://rickandmortyapi.com/graphql",
      "protocol":"https",
      "host":[
        "rickandmortyapi",
        "com"
      ],
      "path":[
        "graphql"
      ]
    }
  },
  "response":[
    {
      "name":"character",
      "originalRequest":{
        "method":"POST",
        "header":[

        ],
        "body":{
          "mode":"graphql",
          "graphql":{
            "query":"query character($id: ID!) {\n  character(id: $id) {\n    __typename\n    id # The id of the character.\n    name # The name of the character.\n    status # The status of the character ('Alive', 'Dead' or 'unknown').\n    species # The species of the character.\n    type # The type or subspecies of the character.\n    gender # The gender of the character ('Female', 'Male', 'Genderless' or 'unknown').\n    # origin # The character's origin location\n    # location # The character's last known location\n    image # Link to the character's image. All images are 300x300px and most are medium shots or portraits since they are intended to be used as avatars.\n    # episode # Episodes in which this character appeared. # Type: NON_NULL\n    created # Time at which the character was created in the database.\n  }\n}",
            "variables":"{\n\t\"id\": 1\n}"
          }
        },
        "url":{
          "raw":"https://rickandmortyapi.com/graphql",
          "protocol":"https",
          "host":[
            "rickandmortyapi",
            "com"
          ],
          "path":[
            "graphql"
          ]
        }
      },
      "status":"OK",
      "code":200,
      "_postman_previewlanguage":"json",
      "header":[
        {
          "key":"Accept-Ranges",
          "value":"bytes"
        },
        {
          "key":"Access-Control-Allow-Credentials",
          "value":"true"
        },
        {
          "key":"Access-Control-Allow-Headers",
          "value":"*"
        },
        {
          "key":"Access-Control-Allow-Methods",
          "value":"POST, GET, HEAD, OPTIONS"
        },
        {
          "key":"Access-Control-Allow-Origin",
          "value":"*"
        },
        {
          "key":"Access-Control-Expose-Headers",
          "value":"*"
        },
        {
          "key":"Access-Control-Max-Age",
          "value":"600"
        },
        {
          "key":"Age",
          "value":"769"
        },
        {
          "key":"Cache-Control",
          "value":"public, s-maxage=900, stale-while-revalidate=900"
        },
        {
          "key":"Content-Length",
          "value":"244"
        },
        {
          "key":"Content-Type",
          "value":"application/json; charset=utf-8"
        },
        {
          "key":"Date",
          "value":"Fri, 23 Sep 2022 09:52:35 GMT"
        },
        {
          "key":"Etag",
          "value":"W/\"f5-prfX+Mk+JL1BE3uszhHEed8uHCc\""
        },
        {
          "key":"Expires",
          "value":"Mon, 26 Sep 2022 09:39:47 GMT"
        },
        {
          "key":"Gcdn-Cache",
          "value":"HIT"
        },
        {
          "key":"Server",
          "value":"Netlify"
        },
        {
          "key":"Via",
          "value":"1.1 varnish"
        },
        {
          "key":"X-Cache",
          "value":"HIT"
        },
        {
          "key":"X-Cache-Hits",
          "value":"1"
        },
        {
          "key":"X-Nf-Request-Id",
          "value":"01GDMW6RFPPKBM97MWWN1HP5B6"
        },
        {
          "key":"X-Powered-By",
          "value":"Stellate"
        },
        {
          "key":"X-Served-By",
          "value":"cache-hhn4074-HHN"
        },
        {
          "key":"X-Timer",
          "value":"S1663926756.857915,VS0,VE1"
        }
      ],
      "cookie":[

      ],
      "body":"{\n    \"data\": {\n        \"character\": {\n            \"__typename\": \"Character\",\n            \"id\": \"1\",\n            \"name\": \"Rick Sanchez\",\n            \"status\": \"Alive\",\n            \"species\": \"Human\",\n            \"type\": \"\",\n            \"gender\": \"Male\",\n            \"image\": \"https://rickandmortyapi.com/api/character/avatar/1.jpeg\",\n            \"created\": \"2017-11-04T18:48:46.250Z\"\n        }\n    }\n}"
    }
  ]
}

The structure seems to match (but maybe I missed smth) apart from the headers and status, which I cannot really generate (I could fake the code and status tho could this be the issue ?).

nohehf commented 2 years ago

Update: adding status and code to the export does not solve the issue

Gbahdeyboh commented 2 years ago

Hi @nohehf.

Can you create an issue for this on postman-app-support and report it as a bug? I tried testing and I ran into the exact same issue.

nohehf commented 2 years ago

Hi @Gbahdeyboh, done here: https://github.com/postmanlabs/postman-app-support/issues/11298 lmk if it seems okay to you

nohehf commented 1 year ago

Marking this issue/feature as stuck till https://github.com/postmanlabs/postman-app-support/issues/11298 is fixed.