Quikly scaffold a postman collection for a GraphQL API. Compatible with Insomnia.

Overview

GraphMan

Quickly scaffold a postman collection for a GraphQL API.

GraphMan CLI generates an complete collection from a GraphQL endpoint, containing one request per query & mutation, with pre filled fields, parameters and variables.

Note: GraphMan is designed for the postman-collection spec 2.1

GraphMan is fully compatible with the Insomnia API Client out of the box!

Motivation

Visualizing and exploring existing graphql APIs can be quite daunting. Using postman to manage all your apis is pretty standard, however creating and maintaining collections is difficult. GraphMan makes thoses things easy, helping you for:

  • Graph discovery
  • Graph testing
  • Collection updating

Usage

GraphMan uses deno as a javascript / typescript runtime. That allows to run the CLI from the file url. To get started:

  • Install deno
  • Run: deno run https://raw.githubusercontent.com/Escape-Technologies/graphman/main/src/index.ts <graphql endpoint url>
  • Import the generated [...].postman_collection.json file in postman.

However if you want to run the CLI locally, clone the repo and run: deno run src/index.ts [url]

Note that deno will ask for network and file-system permissions as it's runtime is secure by default

Examples

You can try graphman on public graphql APIs, and it is a great way to get started with graphQL:

  • Rick&Morty API: deno run https://raw.githubusercontent.com/Escape-Technologies/graphman/main/src/index.ts https://rickandmortyapi.com/graphql
GraphMan collection for the Rick and morty API
Character query for the Rick and morty API collection

Issues and contributions

  • Please open an issue if you encounter bugs, with reproduction steps and error message.
  • For feature requests, please open an issue too
  • Feel free to create merge requests to improve GraphMan !
Comments
  • feat: make graphql pretty

    feat: make graphql pretty

    I ran the final output through the print/parse functions of graphql to remove any unwanted spaces. This should mean we can simplify some of the formatting functions, and rely on this, as well as JSON.stringify later (for variables, etc.)

    lmkwyt

    enhancement 
    opened by notrab 11
  • feat: improve error message when the request fails

    feat: improve error message when the request fails

    Hello, graphman worked with my local backend, nice <3

    I tried to do that

    # create a new token
    $ open https://github.com/settings/tokens/new
    $ export GITHUB_TOKEN="xxxxxxxx"
    # works for me
    $ curl -H "Authorization: bearer $GITHUB_TOKEN" https://api.github.com/graphql
    $ alias graphman="deno  run  https://deno.land/x/[email protected]/src/index.ts"
    $ graphman https://api.github.com/graphql --auth="bearer $GTHUB_TOKEN"
    Creating the postman collection for https://api.github.com/graphql
    ⚠️  ️Deno requests net access to "api.github.com". Run again with --allow-net to bypass this prompt.
       Allow? [y/n (y = yes allow, n = no deny)]  y
    error: Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '__schema')
      const queryTypeName = introspectionQuery.__schema.queryType
                                               ^
        at createPostmanCollection (https://deno.land/x/[email protected]/src/lib.ts:308:44)
        at async https://deno.land/x/[email protected]/src/index.ts:38:20
    

    Reference: https://docs.github.com/en/graphql/guides/forming-calls-with-graphql#communicating-with-graphql

    EDIT:

    The actual issue is the lack of a good error message when the http call fails

    As it turns out it was a typo (thanks for the comments)

    $ graphman https://api.github.com/graphql --auth="bearer $GITHUB_TOKEN"
    Collection saved at ./out/api.github.com-GraphMan.postman_collection.json
    Import it in postman and complete the queries ! 🚀
    
    enhancement good first issue p2 
    opened by jmfayard 7
  • Error: Query type not found

    Error: Query type not found

    I get this error when running the command:

    error: Uncaught (in promise) Error: Query type not found
      if (!queryType) throw new Error("Query type not found");
                            ^
        at createPostmanCollection (https://raw.githubusercontent.com/Escape-Technologies/graphman/main/src/lib.ts:296:25)
        at async https://raw.githubusercontent.com/Escape-Technologies/graphman/main/src/index.ts:23:20
    

    Maybe it is because the type of my query is called "MyAppQuery" instead of "Query"? (same thing for mutations). This is allowed by the GraphQL spec.

    In the introspection query this is indicated by this:

    {
        "_queryType": "MyAppQuery",
        "_mutationType": "MyAppMutation"
        ...
    }
    
    bug good first issue 
    opened by julienFlexsoft 4
  • Unions not yet supported?

    Unions not yet supported?

    Getting an error

    error: Uncaught (in promise) Error: Kind UNION for type WorkItem is not supported yet. Please open an issue.
    

    Is this a known limitation at the moment or maybe I have something configured incorrectly?

    p1 
    opened by acomito 3
  • Include a documentation in the generated collection

    Include a documentation in the generated collection

    GraphQL provides us with the option to include descriptions in our schema. Descriptions can be field or list descriptions. Tools like GraphiQL use these descriptions in the generated documentation for any GraphQL schema.

    These same behaviors can be replicated in collections as well. It helps the consumer of that collection with additional with some additional context.

    enhancement good first issue p2 doing 
    opened by Gbahdeyboh 3
  • Example doesn't work

    Example doesn't work

    I wanted to test just the example deno run https://deno.land/x/[email protected]/src/index.ts https://rickandmortyapi.com/graphql before testing with my application and I immediately got the following error:

    Check https://deno.land/x/[email protected]/src/index.ts
    error: TS2322 [ERROR]: Type 'AliasName<K, A>' is not assignable to type 'string | number | symbol'.
      Type 'K | (string extends A[K] ? K : A[K] extends string ? K | A[K] : K)' is not assignable to type 'string | number | symbol'.
        Type 'string extends A[K] ? K : A[K] extends string ? K | A[K] : K' is not assignable to type 'string | number | symbol'.
          Type 'K | (A[K] extends string ? K | A[K] : K)' is not assignable to type 'string | number | symbol'.
            Type 'A[K] extends string ? K | A[K] : K' is not assignable to type 'string | number | symbol'.
              Type 'K | A[K]' is not assignable to type 'string | number | symbol'.
                Type 'A[K]' is not assignable to type 'string | number | symbol'.
                  Type 'A[string] | A[number] | A[symbol]' is not assignable to type 'string | number | symbol'.
                    Type 'A[K]' is not assignable to type 'symbol'.
                      Type 'A[string] | A[number] | A[symbol]' is not assignable to type 'symbol'.
                        Type 'A[string]' is not assignable to type 'symbol'.
                          Type 'A[K] extends string ? K | A[K] : K' is not assignable to type 'symbol'.
                            Type 'K | A[K]' is not assignable to type 'symbol'.
                              Type 'keyof A & K' is not assignable to type 'symbol'.
                                Type 'string extends A[K] ? K : A[K] extends string ? K | A[K] : K' is not assignable to type 'symbol'.
                                  Type 'K | (A[K] extends string ? K | A[K] : K)' is not assignable to type 'symbol'.
                                    Type 'keyof A & K' is not assignable to type 'symbol'.
                                      Type 'AliasName<keyof T, A>' is not assignable to type 'string | number | symbol'.
                                        Type 'keyof T | (string extends A[keyof A & keyof T] ? keyof A & keyof T : A[keyof A & keyof T] extends string ? (keyof A & keyof T) | A[keyof A & keyof T] : keyof A & keyof T)' is not assignable to type 'string | number | symbol'.
                                          Type 'string extends A[keyof A & keyof T] ? keyof A & keyof T : A[keyof A & keyof T] extends string ? (keyof A & keyof T) | A[keyof A & keyof T] : keyof A & keyof T' is not assignable to type 'string | number | symbol'.
                                            Type '(keyof A & keyof T) | (A[keyof A & keyof T] extends string ? (keyof A & keyof T) | A[keyof A & keyof T] : keyof A & keyof T)' is not assignable to type 'string | number | symbol'.
                                              Type 'A[keyof A & keyof T] extends string ? (keyof A & keyof T) | A[keyof A & keyof T] : keyof A & keyof T' is not assignable to type 'string | number | symbol'.
                                                Type '(keyof A & keyof T) | A[keyof A & keyof T]' is not assignable to type 'string | number | symbol'.
                                                  Type 'A[keyof A & keyof T]' is not assignable to type 'string | number | symbol'.
                                                    Type 'A[string] | A[number] | A[symbol]' is not assignable to type 'string | number | symbol'.
                                                      Type 'A[string]' is not assignable to type 'string | number | symbol'.
                                                        Type 'A[string]' is not assignable to type 'symbol'.
                                                          Type 'A[keyof A & keyof T]' is not assignable to type 'symbol'.
                                                            Type 'A[string] | A[number] | A[symbol]' is not assignable to type 'symbol'.
                                                              Type 'A[string]' is not assignable to type 'symbol'.
                                                                Type 'A[keyof A & keyof T] extends string ? (keyof A & keyof T) | A[keyof A & keyof T] : keyof A & keyof T' is not assignable to type 'symbol'.
                                                                  Type '(keyof A & keyof T) | A[keyof A & keyof T]' is not assignable to type 'symbol'.
                                                                    Type 'keyof A & keyof T' is not assignable to type 'symbol'.
                                                                      Type 'string extends A[keyof A & keyof T] ? keyof A & keyof T : A[keyof A & keyof T] extends string ? (keyof A & keyof T) | A[keyof A & keyof T] : keyof A & keyof T' is not assignable to type 'symbol'.
                                                                        Type '(keyof A & keyof T) | (A[keyof A & keyof T] extends string ? (keyof A & keyof T) | A[keyof A & keyof T] : keyof A & keyof T)' is not assignable to type 'symbol'.
                                                                          Type 'keyof A & keyof T' is not assignable to type 'symbol'.
                                                                            Type 'AliasName<string, A> | AliasName<number, A> | AliasName<symbol, A>' is not assignable to type 'string | number | symbol'.
                                                                              Type 'AliasName<string, A>' is not assignable to type 'string | number | symbol'.
                                                                                Type 'string | (string extends A[keyof A & string] ? keyof A & string : A[keyof A & string] extends string ? (keyof A & string) | A[keyof A & string] : keyof A & string)' is not assignable to type 'string | number | symbol'.
                                                                                  Type 'string extends A[keyof A & string] ? keyof A & string : A[keyof A & string] extends string ? (keyof A & string) | A[keyof A & string] : keyof A & string' is not assignable to type 'string | number | symbol'.
                                                                                    Type '(keyof A & string) | (A[keyof A & string] extends string ? (keyof A & string) | A[keyof A & string] : keyof A & string)' is not assignable to type 'string | number | symbol'.
                                                                                      Type 'A[keyof A & string] extends string ? (keyof A & string) | A[keyof A & string] : keyof A & string' is not assignable to type 'string | number | symbol'.
                                                                                        Type '(keyof A & string) | A[keyof A & string]' is not assignable to type 'string | number | symbol'.
                                                                                          Type 'A[keyof A & string]' is not assignable to type 'string | number | symbol'.
                                                                                            Type 'A[string]' is not assignable to type 'string | number | symbol'.
                                                                                              Type 'A[string]' is not assignable to type 'symbol'.
                                                                                                Type 'A[keyof A & string]' is not assignable to type 'symbol'.
                                                                                                  Type 'A[string]' is not assignable to type 'symbol'.
                                                                                                    Type 'A[keyof A & string] extends string ? (keyof A & string) | A[keyof A & string] : keyof A & string' is not assignable to type 'symbol'.
                                                                                                      Type '(keyof A & string) | A[keyof A & string]' is not assignable to type 'symbol'.
                                                                                                        Type 'keyof A & string' is not assignable to type 'symbol'.
                                                                                                          Type 'string extends A[keyof A & string] ? keyof A & string : A[keyof A & string] extends string ? (keyof A & string) | A[keyof A & string] : keyof A & string' is not assignable to type 'symbol'.
                                                                                                            Type '(keyof A & string) | (A[keyof A & string] extends string ? (keyof A & string) | A[keyof A & string] : keyof A & string)' is not assignable to type 'symbol'.
                                                                                                              Type 'keyof A & string' is not assignable to type 'symbol'.
                                                                                                                Type 'AliasName<string, A>' is not assignable to type 'symbol'.
                                                                                                                  Type 'AliasName<keyof T, A>' is not assignable to type 'symbol'.
                                                                                                                    Type 'AliasName<K, A>' is not assignable to type 'symbol'.
                                                                                                                      Type 'K | (string extends A[K] ? K : A[K] extends string ? K | A[K] : K)' is not assignable to type 'symbol'.
                                                                                                                        Type 'K' is not assignable to type 'symbol'.
                                                                                                                          Type 'keyof T' is not assignable to type 'symbol'.
                                                                                                                            Type 'AliasName<keyof T, A>' is not assignable to type 'symbol'.
                                                                                                                              Type 'keyof T | (string extends A[keyof A & keyof T] ? keyof A & keyof T : A[keyof A & keyof T] extends string ? (keyof A & keyof T) | A[keyof A & keyof T] : keyof A & keyof T)' is not assignable to type 'symbol'.
                                                                                                                                Type 'keyof T' is not assignable to type 'symbol'.
                                                                                                                                  Type 'string | number | symbol' is not assignable to type 'symbol'.
                                                                                                                                    Type 'string' is not assignable to type 'symbol'.
                                                                                                                                      Type 'AliasName<string, A> | AliasName<number, A> | AliasName<symbol, A>' is not assignable to type 'symbol'.
                                                                                                                                        Type 'AliasName<string, A>' is not assignable to type 'symbol'.
                                                                                                                                          Type 'string | (string extends A[keyof A & string] ? keyof A & string : A[keyof A & string] extends string ? (keyof A & string) | A[keyof A & string] : keyof A & string)' is not assignable to type 'symbol'.
                                                                                                                                            Type 'string' is not assignable to type 'symbol'.
    > = { [K in keyof T as AliasName<K, A>]: T[K] };
                           ~~~~~~~~~~~~~~~
        at https://deno.land/[email protected]/flags/mod.ts:72:24
    
    bug 
    opened by rmeja 3
  • Interfaces are not supported

    Interfaces are not supported

    Hello, since it's asked in the error message and I didn't find an issue already referencing this - running graphman on my schema returns this error:

    error: Uncaught (in promise) Error: Kind INTERFACE for type <TheInterfaceName> is not supported yet. Please open an issue.
    

    Here is an exemple with a public schema:

    deno run https://deno.land/x/[email protected]/src/cli.ts https://swapi-graphql.netlify.app/.netlify/functions/index
    
    p1 
    opened by antogyn 2
  • Mutations not being separated into folder

    Mutations not being separated into folder

    Hello, I saw that this issue was closed a few days ago (https://github.com/Escape-Technologies/graphman/issues/30) however when I run graphman, everything is still being placed under the queries folder.

    I tried it with other APIs, such as this one: https://graphql-compose.herokuapp.com/northwind/

    The end result is something similar to the below, as can be seen, it has mutations but it is stored under the queries array.

    Screenshot 2022-09-28 at 15 47 14

    As a separate question (not sure where to ask / apologies if it should be a separate issue). Is there a way to organize the apis into named collections? i.e. authentication, checkout etc?

    bug p1 
    opened by bynho 2
  • Feat: pass options as flags

    Feat: pass options as flags

    #12 and #9 features, and basically any future optional parameter, should be passed through flags. For instance:

    • Changing file output should be done via: --output <filename> or -o <filename>
    • Passing a bearer token should be done via: --bearer <token> Just wondering if I'll write the parser from scratch or use one to ensure robustness.
    opened by nohehf 1
  • refacto: clarify code and separate concerns

    refacto: clarify code and separate concerns

    Separate the lib.ts file so that it's easier to understand & upgrade GraphMan. Strings formatting, parsing, and output should be in separated modules.

    opened by nohehf 1
  • Feat/interface and union types support

    Feat/interface and union types support

    Description

    Fixes #44 and #47

    Adds support for UNION and INTERFACE types. INTERFACE is treated as an OBJECT. UNION support remains basic, it will not prefill the union with subtypes but is now accepted by the parser and present in the output as a commented type. Better support could be done, but my bandwidth on this project is too thin now, and UNIONS don't seem to be used a lot.

    Checklist:

    • [x] I have performed a self-review of my own code
    • [x] I have ran deno task ci to ensure that my code is formatted and linted.
    • [x] I have linked the related issue (if there is no related issue please create one)
    • [ ] ~~I have added tests if applicable~~ (needs tests to be ready)
    opened by nohehf 0
  • feat: use the postman-collections sdk

    feat: use the postman-collections sdk

    Currently, the format.ts module is building the postman collection programmatically from scratch. However, Postman has an npm package: https://github.com/postmanlabs/postman-collection that provides an SDK for doing so. I decided not to use it in the fireplace as deno support for npm packages was not a thing back then, but it has evolved a lot since then. It would be interesting to use the SDK for cleaner code, reducing the code-base and future-proofing.

    Edit: as of deno 1.26.x npm support is still unstable, I'll get onto this issue when I'm satisfied with this: https://github.com/denoland/deno/issues/15960

    enhancement good first issue p3 
    opened by nohehf 0
  • Build and publish an npm package from graphman

    Build and publish an npm package from graphman

    Deno has the capability to be exported as an npm package, which would allow GraphMan to be used as a node module (for now it's only programmatically usable from deno). See: https://deno.land/[email protected]/node/dnt & https://github.com/denoland/dnt . This needs a little reflection and testing to be done right, but it could be included in a CI at the end to build and deploy new versions when a new tag is added.

    enhancement p3 
    opened by nohehf 0
  • feat: basic mock

    feat: basic mock

    Description

    Fixes #33

    Generates a basic response example for each query. Not perfect for now but useful however as it generates a base that can be manually extended by the users. Improvements will be made.

    Stuck: example responses are ok in the collection, however, when generating a mock server with postman it doesn't pick up the correct example for the request. I believe that could be an issue on Postman side, will investigate in #33 before merging.

    Checklist:

    • [x] I have performed a self-review of my own code
    • [x] I have ran deno task ci to ensure that my code is formatted and linted.
    • [x] I have linked the related issue (if there is no related issue please create one)
    • [ ] ~~I have added tests if applicable~~ (needs tests to be ready)
    opened by nohehf 0
  • Generate mock responses for mutations and queries.

    Generate mock responses for mutations and queries.

    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.

    enhancement p2 doing stuck 
    opened by Gbahdeyboh 6
  • Generate sample test cases for collections

    Generate sample test cases for collections

    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.

    Postman has something called postman scripts that can be used to write unit-like tests. Its assertion and test suite were built atop mocha and chai making it quite similar in usage to them.

    Postman scripts can be written and run in the tests tab in Postman, which is a NodeJS runtime environment for collections.

    Because of the declarative nature of GraphQL, it is possible to generate sample test cases for GraphQL APIs on postman collections. It doesn't have to be anything fancy, it could be just very basic data validation checks for s start.

    I am not familiar with what Escape provides, but we could also have a few security test cases that are auto-generated and can be run on the fly.

    enhancement p4 
    opened by Gbahdeyboh 1
Releases(v1.1.4)
Owner
Escape – GraphQL Security
Never worry about your GraphQL Security again
Escape – GraphQL Security
🦉 Soothing pastel theme for Insomnia!

Catppuccin for Insomnia Usage Install In Insomnia, go to Application and select Preferences Click on Plugins Paste insomnia-plugin-catppuccin into the

Catppuccin 21 Dec 31, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
A Leaderscore app that send data to an API created from Postman and allow users to save names and scores in a table. Built with JavaScript

Leaderboard The leaderboard website displays scores submitted by different players. It also allows you to submit your score. All data is preserved tha

Anicet Murhula 11 May 16, 2022
Convert your Postman documentation in a github´s readme.md ready format

Postman 2 Markdown Converter For that only time you need to convert your Postman documentation in a github´s readme ready format! Features & Problems

Andres Bastias 0 Sep 18, 2022
next-graphql-server is a library for building production-grade GraphQL servers using Next.js with API Routes

next-graphql-server next-graphql-server is an easy to use Next.js library for creating performant GraphQL endpoints on top of Next.js API Routes. Star

Jakub Neander 82 Nov 21, 2022
Base Rails app that includes login, social login, homepage, and basic model for serving as a scaffold app.

Rails7Base I created the Rails7Base as a scaffold application. Countless times, I had to create apps that must have the following features: Login syst

Chim Kan 14 Jul 2, 2022
A toolkit to rapidly scaffold out a new tauri-apps project using the framework of their choice.

create-tauri-app Component Version create-tauri-app About Tauri Tauri is a polyglot and generic system that is very composable and allows engineers to

Tauri 408 Jan 4, 2023
T6e: scaffold any local template into a custom file

T6e is a small tool (no dependencies, 50 lines of code) to scaffold any local template and speed up the creation of files in a project using your custom templates or templates from the community.

Butopen 4 Dec 23, 2022
A starter kit for scaffold-eth projects

?? scaffold-eth-cli As simple as running this in your terminal: npx scaffold-eth Clones scaffold-eth into the current folder as fast as possible ⚡️ ⁉

qedk 3 Jun 11, 2022
Scaffold a full-stack SvelteKit application with tRPC and WindiCSS out of the box

create-sweet-app Interactive CLI to quickly set up an opinionated, full-stack, typesafe SvelteKit project. Inspired by the T3 Stack and create-t3-app

David Hrabě 10 Dec 16, 2022
CLI to scaffold tailwindcss-ready projects

Create TailwindCSS Project (create-tw) The easiest way to get started with TailwindCSS. It uses popular scaffolding scripts like create-next-app or cr

Andrej Jurkin 216 Dec 29, 2022
The proposal of this repository is having a scaffold with some scenarios where you can challenge your front-end knowledge.

Frontend Kata / Interview ?? Hello developer! The proposal of this repository is having a scaffold with some scenarios where you can challenge your fr

Adrián Ferrera González 2 Nov 11, 2022
A sdk scaffold with typescript.

sdk-scaffold A sdk scaffold with vite & typescript. Start git clone --depth=1 https://github.com/Alioth1017/sdk-scaffold my-sdk cd my-sdk pnpm i confi

Alioth 6 Sep 7, 2022
NextJS with GraphQL using type-graphl and graphql-codegen adoptable dogs example code

This is a Next.js project bootstrapped with create-next-app. Getting Started First, run the development server: npm run dev # or yarn dev Open http://

Jack Herrington 2 Mar 31, 2022
GraphQL-first boilerplate that scales with TypeScript + Node Express + Apollo GraphQL APIs.

graphql-typescript-boilerplate A boilerplate project for quickly building Graphql APIs and with typescript ?? Installation Install the dependencies: y

Youssef Hajjari 6 May 15, 2022
GraphQL Hive provides all the tools the get visibility of your GraphQL architecture at all stages, from standalone APIs to composed schemas (Federation, Stitching)

GraphQL Hive GraphQL Hive provides all the tools the get visibility of your GraphQL architecture at all stages, from standalone APIs to composed schem

Kamil Kisiela 184 Dec 21, 2022
Wraps postgres API in a pg compatible API.

postgres/pg compatibility layer Wraps postgres API in a pg compatible API.

Gajus Kuizinas 18 Oct 16, 2022