Skip to content

Commit 702ed60

Browse files
committed
Update with improvements
1 parent dc1dc84 commit 702ed60

File tree

3 files changed

+97
-42
lines changed

3 files changed

+97
-42
lines changed

readme.md

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ Persisted GraphQL queries allow a GraphQL client to optimistically send a hash
44
of the query instead of the full query; if the server has seen the query
55
before, it can satisfy the request. This saves network overhead and makes it
66
possible to move to `GET` requests instead of `POST`. The primary benefit of
7-
`GET` requests is that they can be easily cached at the edge (e.g., with
8-
Varnish).
7+
`GET` requests is that they can be cached at the edge (e.g., with Varnish).
98

109
This plugin requires [WPGraphQL][wp-graphql] 0.2.0 or newer.
1110

@@ -17,16 +16,24 @@ https://github.com/apollographql/apollo-link-persisted-queries#automatic-persist
1716

1817
This plugin aims to be compatible with that implementation, but will work with
1918
any client that sends a `queryId` alongside the `query`. Make sure your client
20-
also sends `operationName` with the optimistic request.
19+
also sends `operationName` or `operation_name` with the optimistic request.
2120

2221
## Implementation
2322

2423
When the client provides a query hash or ID, that query will be persisted in a
25-
custom post type. By default, this post type will be visible in the dashboard
26-
only to admins.
24+
custom post type. By default, this post type will not be visible in the
25+
dashboard.
2726

2827
Query IDs are case-insensitive (i.e., `MyQuery` and `myquery` are equivalent).
2928

29+
## Caching
30+
31+
This plugin does nothing to implement, amend, or purge page (edge) caching. It
32+
is up to you to make page caching work for you. Remember that WPGraphQL has a
33+
single monolithic endpoint at `/graphql` and persisted query requests will
34+
arrive as `GET` requests to that endpoint with unique query strings. Cache
35+
wisely!
36+
3037
## Filters
3138

3239
### `graphql_persisted_queries_post_type`
@@ -35,11 +42,10 @@ Query IDs are case-insensitive (i.e., `MyQuery` and `myquery` are equivalent).
3542
- The custom post type used to persist queries. If empty, queries will not be
3643
persisted.
3744

38-
### `graphql_persisted_queries_show_in_graphql`
45+
### `graphql_persisted_queries_post_type_args`
3946

40-
- Default: `false`
41-
- Whether the custom post type will itself be exposed via GraphQL. Enabling
42-
allows insight into which queries are persisted.
47+
- Args passed to register_post_type for custom post type. Filter to expose the
48+
custom post type in the admin UI or in GraphQL:
4349

4450
```
4551
query PersistedQueryQuery {
@@ -53,7 +59,13 @@ Query IDs are case-insensitive (i.e., `MyQuery` and `myquery` are equivalent).
5359
}
5460
```
5561

56-
If you'd like to further customize the custom post type, filter
57-
`register_post_type_args`.
62+
### `graphql_persisted_queries_load_query`
63+
64+
- Default: `null`
65+
- Override the default query loading implementation.
66+
67+
### `graphql_persisted_queries_save_query`
68+
69+
- Override the query (post data) that will be persisted.
5870

5971
[wp-graphql]: https://github.com/wp-graphql/wp-graphql

src/loader.php

Lines changed: 71 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,42 @@ public function get_http_status_code( $status_code, $response ) {
8585
return $status_code;
8686
}
8787

88+
/**
89+
* Be a little flexible in how operation name is sent.
90+
*
91+
* @param array $request_data Request data.
92+
* @return string
93+
*/
94+
private function get_operation_name( $request_data ) {
95+
foreach( [ 'operationName', 'operation_name' ] as $key ) {
96+
if ( ! empty( $request_data[ $key ] ) ) {
97+
return $request_data[ $key ];
98+
}
99+
}
100+
101+
return 'UnnamedQuery';
102+
}
103+
88104
/**
89105
* Attempts to load a persisted query corresponding to a query ID (hash).
90106
*
91107
* @param string $query_id Query ID
92108
* @return string Query
93109
*/
94-
public function load( $query_id ) {
110+
private function load( $query_id ) {
111+
/**
112+
* Allow other implementors to load queries.
113+
*
114+
* @param string $query Persisted query.
115+
* @param string $query_id Query ID.
116+
* @since 1.1.0
117+
*/
118+
$query = apply_filters( "{$this->namespace}_load_query", null, $query_id );
119+
if ( $query ) {
120+
return $query;
121+
}
122+
123+
// If query has been persisted to our custom post type, return it.
95124
$post = get_page_by_path( $query_id, 'OBJECT', $this->post_type );
96125

97126
return isset( $post->post_content ) ? $post->post_content : null;
@@ -116,7 +145,7 @@ public function process_request_data( $request_data ) {
116145

117146
// Client sends *both* queryId and query == request to persist query.
118147
if ( $has_query_id && $has_query ) {
119-
$this->save( $query_id, $request_data['query'], $request_data['operationName'] );
148+
$this->save( $query_id, $request_data['query'], $this->get_operation_name( $request_data ) );
120149
}
121150

122151
// Client sends queryId but *not* query == optimistic request to use
@@ -137,36 +166,34 @@ public function process_request_data( $request_data ) {
137166
}
138167

139168
/**
140-
* Register the persisted query post type. We could filter a lot of individual
141-
* values here, but we won't. If further customization is wanted, filter
142-
* register_post_type_args.
169+
* Register the persisted query post type.
143170
*
144171
* @return void
145172
*/
146173
private function register_post_type() {
174+
$post_type_args = [
175+
'label' => 'Queries',
176+
'public' => false,
177+
'query_var' => false,
178+
'rewrite' => false,
179+
'show_in_rest' => false,
180+
'show_in_graphql' => false,
181+
'graphql_single_name' => 'persistedQuery',
182+
'graphql_plural_name' => 'persistedQueries',
183+
'show_ui' => false,
184+
'supports' => [ 'title', 'editor' ],
185+
];
186+
147187
/**
148-
* Whether persisted queries can be themselves queried via GraphQL. 💅
188+
* Post type args for persisted queries. Filter this to expose the post type
189+
* in the UI or in GraphQL.
149190
*
150-
* @param bool $show_in_graphql Show in GraphQL?
151-
* @since 1.0.0
191+
* @param bool $post_type_args Register post type args.
192+
* @since 1.1.0
152193
*/
153-
$show_in_graphql = apply_filters( "{$this->namespace}_show_in_graphql", false );
154-
155-
register_post_type(
156-
$this->post_type,
157-
[
158-
'label' => 'Queries',
159-
'public' => false,
160-
'query_var' => false,
161-
'rewrite' => false,
162-
'show_in_rest' => false,
163-
'show_in_graphql' => $show_in_graphql,
164-
'graphql_single_name' => 'persistedQuery',
165-
'graphql_plural_name' => 'persistedQueries',
166-
'show_ui' => is_admin(),
167-
'supports' => [ 'title', 'editor' ],
168-
]
169-
);
194+
$post_type_args = apply_filters( "{$this->namespace}_post_type_args", $post_type_args );
195+
196+
register_post_type( $this->post_type, $post_type_args );
170197
}
171198

172199
/**
@@ -177,19 +204,34 @@ private function register_post_type() {
177204
* @param string $name Operation name
178205
* @return void
179206
*/
180-
public function save( $query_id, $query, $name = 'UnnamedQuery' ) {
207+
private function save( $query_id, $query, $name = 'UnnamedQuery' ) {
181208
// Check to see if the query has already been persisted. If so, we're done.
182209
if ( ! empty( $this->load( $query_id ) ) ) {
183210
return;
184211
}
185212

186-
// Persist the query.
187-
wp_insert_post( [
213+
$post_data = [
188214
'post_content' => $query,
189215
'post_name' => $query_id,
190216
'post_title' => $name,
191217
'post_status' => 'publish',
192218
'post_type' => $this->post_type,
193-
] );
219+
];
220+
221+
/**
222+
* Allow implementors to override persisted query.
223+
*
224+
* @param bool $post_data Post data for persisted query.
225+
* @param string $query_id Query ID.
226+
* @since 1.1.0
227+
*/
228+
$post_data = apply_filters( "{$this->namespace}_save_query", $post_data, $query_id );
229+
230+
if ( empty( $post_data ) ) {
231+
return;
232+
}
233+
234+
// Persist the query.
235+
wp_insert_post( $post_data );
194236
}
195237
}

wp-graphql-persisted-queries.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Plugin URI: https://github.com/Quartz/wp-graphql-persisted-queries
55
* Description: Provides persistence to GraphQL queries allowing them to be queried by ID or hash. Requires WPGraphQL 0.2.0 or newer.
66
* Author: Chris Zarate, Quartz
7-
* Version: 1.0.0
7+
* Version: 1.1.0
88
* Author URI: https://qz.com/
99
*
1010
* @package wp-graphql-persisted-queries
@@ -14,4 +14,5 @@
1414

1515
require_once( __DIR__ . '/src/loader.php' );
1616

17-
add_action( 'graphql_init', array( new Loader(), 'init' ), 10, 0 );
17+
// Higher priority allows other code at default priority to run first.
18+
add_action( 'graphql_init', array( new Loader(), 'init' ), 20, 0 );

0 commit comments

Comments
 (0)