X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fgraphql-client;a=blobdiff_plain;f=README.md;h=caebdfd8947135e54e652cb4197413654ecbf295;hp=5f4df5bf6f1a74313a74621c0120c8c3ee17ddd0;hb=HEAD;hpb=a1190420f86c2511c10c3ae0664d299447079a64 diff --git a/README.md b/README.md index 5f4df5b..fd618b9 100644 --- a/README.md +++ b/README.md @@ -1,173 +1,257 @@ # NAME -GraphQL::Client - A GraphQL client +graphql - Command-line GraphQL client # VERSION -version 0.600 +version 0.605 # SYNOPSIS - my $graphql = GraphQL::Client->new(url => 'http://localhost:4000/graphql'); + graphql [ [--variables JSON] | [--variable KEY=VALUE]... ] + [--operation-name NAME] [--transport KEY=VALUE]... + [--[no-]unpack] [--filter JSONPATH] + [--format json|json:pretty|yaml|perl|csv|tsv|table] [--output FILE] - # Example: Hello world! + graphql --version|--help|--manual - my $response = $graphql->execute('{hello}'); +# DESCRIPTION - # Example: Kitchen sink +`graphql` is a command-line program for executing queries and mutations on +a [GraphQL](https://graphql.org/) server. - my $query = q[ - query GetHuman { - human(id: $human_id) { - name - height - } - } - ]; - my $variables = { - human_id => 1000, - }; - my $operation_name = 'GetHuman'; - my $transport_options = { - headers => { - authorization => 'Bearer s3cr3t', - }, - }; - my $response = $graphql->execute($query, $variables, $operation_name, $transport_options); - - # Example: Asynchronous with Mojo::UserAgent (promisify requires Future::Mojo) - - my $ua = Mojo::UserAgent->new; - my $graphql = GraphQL::Client->new(ua => $ua, url => 'http://localhost:4000/graphql'); - - my $future = $graphql->execute('{hello}'); - - $future->promisify->then(sub { - my $response = shift; - ... - }); +# INSTALL -# DESCRIPTION +There are several ways to install `graphql` to your system. -`GraphQL::Client` provides a simple way to execute [GraphQL](https://graphql.org/) queries and -mutations on a server. +## from CPAN -This module is the programmatic interface. There is also a [graphql](#cli-program). +You can install `graphql` using [cpanm](https://metacpan.org/pod/cpanm): -GraphQL servers are usually served over HTTP. The provided transport, [GraphQL::Client::http](https://metacpan.org/pod/GraphQL%3A%3AClient%3A%3Ahttp), lets -you plug in your own user agent, so this client works naturally with [HTTP::Tiny](https://metacpan.org/pod/HTTP%3A%3ATiny), -[Mojo::UserAgent](https://metacpan.org/pod/Mojo%3A%3AUserAgent), and more. You can also use [HTTP::AnyUA](https://metacpan.org/pod/HTTP%3A%3AAnyUA) middleware. + cpanm GraphQL::Client -# ATTRIBUTES +## from GitHub -## url +You can also choose to download `graphql` as a self-contained executable: -The URL of a GraphQL endpoint, e.g. `"http://myapiserver/graphql"`. + curl -OL https://raw.githubusercontent.com/chazmcgarvey/graphql-client/solo/graphql + chmod +x graphql -## class +To hack on the code, clone the repo instead: -The package name of a transport. + git clone https://github.com/chazmcgarvey/graphql-client.git + cd graphql-client + make bootstrap # installs dependencies; requires cpanm -By default this is automatically determined from the protocol portion of the ["url"](#url). +# OPTIONS -## transport +## `--url URL` -The transport object. +The URL of the GraphQL server endpoint. -By default this is automatically constructed based on the ["class"](#class). +If no `--url` option is given, the first argument is assumed to be the URL. -## unpack +This option is required. -Whether or not to "unpack" the response, which enables a different style for error-handling. +Alias: `-u` -Default is 0. +## `--query STR` -See ["ERROR HANDLING"](#error-handling). +The query or mutation to execute. -# METHODS +If no `--query` option is given, the next argument (after URL) is assumed to be the query. -## new +If the value is "-" (which is the default), the query will be read from `STDIN`. - $graphql = GraphQL::Client->new(%attributes); +See: [https://graphql.org/learn/queries/](https://graphql.org/learn/queries/) -Construct a new client. +Alias: `--mutation` -## execute +## `--variables JSON` - $response = $graphql->execute($query); - $response = $graphql->execute($query, \%variables); - $response = $graphql->execute($query, \%variables, $operation_name); - $response = $graphql->execute($query, \%variables, $operation_name, \%transport_options); - $response = $graphql->execute($query, \%variables, \%transport_options); +Provide the variables as a JSON object. -Execute a request on a GraphQL server, and get a response. +Aliases: `--vars`, `-V` -By default, the response will either be a hashref with the following structure or a [Future](https://metacpan.org/pod/Future) that -resolves to such a hashref, depending on the transport and how it is configured. +## `--variable KEY=VALUE` - { - data => { - field1 => {...}, # or [...] - ... - }, - errors => [ - { message => 'some error message blah blah blah' }, - ... - ], - } +An alternative way to provide variables one at a time. This option can be repeated to provide +multiple variables. -Note: Setting the ["unpack"](#unpack) attribute affects the response shape. +If used in combination with ["--variables JSON"](#variables-json), this option is silently ignored. -# ERROR HANDLING +See: [https://graphql.org/learn/queries/#variables](https://graphql.org/learn/queries/#variables) -There are two different styles for handling errors. +Aliases: `--var`, `-d` -If ["unpack"](#unpack) is 0 (off), every response -- whether success or failure -- is enveloped like this: +## `--operation-name NAME` - { - data => {...}, - errors => [...], - } +Inform the server which query/mutation to execute. + +Alias: `-n` + +## `--output FILE` + +Write the response to a file instead of STDOUT. + +Alias: `-o` + +## `--transport KEY=VALUE` + +Key-value pairs for configuring the transport (usually HTTP). + +Alias: `-t` + +## `--format STR` -where `data` might be missing or undef if errors occurred (though not necessarily) and `errors` -will be missing if the response completed without error. +Specify the output format to use. See ["FORMAT"](#format). -It is up to you to check for errors in the response, so your code might look like this: +Alias: `-f` - my $response = $graphql->execute(...); - if (my $errors = $response->{errors}) { - # handle $errors +## `--unpack` + +Enables unpack mode. + +By default, the response structure is printed as-is from the server, and the program exits 0. + +When unpack mode is enabled, if the response completes with no errors, only the data section of +the response is printed and the program exits 0. If the response has errors, the whole response +structure is printed as-is and the program exits 1. See ["EXAMPLES"](#examples) to see what this looks like in +practice. + +Use `--no-unpack` to disable if unpack mode was enabled via `GRAPHQL_CLIENT_OPTIONS`. + +## `--filter JSONPATH` + +Filter the response based on a [JSONPath](https://metacpan.org/pod/JSON%3A%3APath#SYNOPSIS) expression. + +Requires [JSON::Path](https://metacpan.org/pod/JSON%3A%3APath). + +Alias: `-p` + +# FORMAT + +The argument for ["--format STR"](#format-str) can be one of: + +- `csv` - Comma-separated values (requires [Text::CSV](https://metacpan.org/pod/Text%3A%3ACSV)) +- `json:pretty` - Human-readable JSON (default) +- `json` - JSON +- `perl` - Perl code (requires [Data::Dumper](https://metacpan.org/pod/Data%3A%3ADumper)) +- `table` - Table (requires [Text::Table::Any](https://metacpan.org/pod/Text%3A%3ATable%3A%3AAny)) +- `tsv` - Tab-separated values (requires [Text::CSV](https://metacpan.org/pod/Text%3A%3ACSV)) +- `yaml` - YAML (requires [YAML](https://metacpan.org/pod/YAML)) + +The `csv`, `tsv`, and `table` formats will only work if the response has a particular shape: + + { + "data" : { + "onefield" : [ + { + "key" : "value", + ... + }, + ... + ] + } } - else { - my $data = $response->{data}; - # do something with $data + +or + + { + "data" : { + "onefield" : [ + "value", + ... + ] + } } -If `unpack` is 1 (on), then ["execute"](#execute) will return just the data if there were no errors, -otherwise it will throw an exception. So your code would instead look like this: +If the response cannot be formatted, the default format will be used instead, an error message will +be printed to STDERR, and the program will exit 3. + +Table formatting can be done by one of several different modules, each with its own features and +bugs. The default module is [Text::Table::Tiny](https://metacpan.org/pod/Text%3A%3ATable%3A%3ATiny), but this can be overridden using the +`PERL_TEXT_TABLE` environment variable if desired, like this: + + PERL_TEXT_TABLE=Text::Table::HTML graphql ... -f table + +The list of supported modules is at ["@BACKENDS" in Text::Table::Any](https://metacpan.org/pod/Text%3A%3ATable%3A%3AAny#BACKENDS). + +# EXAMPLES + +Different ways to provide the query/mutation to execute: + + graphql http://myserver/graphql {hello} + + echo {hello} | graphql http://myserver/graphql + + graphql http://myserver/graphql < {hello} + > END + + graphql http://myserver/graphql + Interactive mode engaged! Waiting for a query on ... + {hello} + ^D + +Execute a query with variables: + + graphql http://myserver/graphql < query HeroNameAndFriends($episode: Episode) { + > hero(episode: $episode) { + > name + > friends { + > name + > } + > } + > } + > END - my $data = eval { $graphql->execute(...) }; - if (my $error = $@) { - # handle errors + graphql http://myserver/graphql --vars '{"episode":"JEDI"}' + +Configure the transport: + + graphql http://myserver/graphql {hello} -t headers.authorization='Basic s3cr3t' + +This example shows the effect of ["--unpack"](#unpack): + + graphql http://myserver/graphql {hello} + + # Output: + { + "data" : { + "hello" : "Hello world!" + } } - else { - # do something with $data + + graphql http://myserver/graphql {hello} --unpack + + # Output: + { + "hello" : "Hello world!" } -Or if you want to handle errors in a different stack frame, your code is simply this: +# ENVIRONMENT + +Some environment variables affect the way `graphql` behaves: + +- `GRAPHQL_CLIENT_DEBUG` - Set to 1 to print diagnostic messages to STDERR. +- `GRAPHQL_CLIENT_HTTP_USER_AGENT` - Set the HTTP user agent string. +- `GRAPHQL_CLIENT_OPTIONS` - Set the default set of options. +- `PERL_TEXT_TABLE` - Set table format backend; see ["FORMAT"](#format). - my $data = $graphql->execute(...); - # do something with $data +# EXIT STATUS -Both styles map to [Future](https://metacpan.org/pod/Future) responses intuitively. If `unpack` is 0, the response always resolves -to the envelope structure. If `unpack` is 1, successful responses will resolve to just the data and -errors will fail/reject. +Here is a consolidated summary of what exit statuses mean: + +- `0` - Success +- `1` - Client or server errors +- `2` - Option usage is wrong +- `3` - Could not format the response as requested # SEE ALSO -- [graphql](https://metacpan.org/pod/graphql) - CLI program -- [GraphQL](https://metacpan.org/pod/GraphQL) - Perl implementation of a GraphQL server -- [https://graphql.org/](https://graphql.org/) - GraphQL project website +- [GraphQL::Client](https://metacpan.org/pod/GraphQL%3A%3AClient) - Programmatic interface # BUGS @@ -180,7 +264,11 @@ feature. # AUTHOR -Charles McGarvey +Charles McGarvey + +# CONTRIBUTOR + +jwright # COPYRIGHT AND LICENSE