Skip to content

Navigation Menu

Sign in
Sign up

How to setup Persisted Queries in lighthouse? #2628

Unanswered
hassan-index asked this question in Q&A
Discussion options

I am using Lighthouse version 6.45.0 in my Laravel project, and the frontend is built with Vue 3. I have already set up my Apollo.js code in the frontend for Persisted Queries. However, I encounter an error with the code PERSISTED_QUERY_NOT_FOUND whenever I make an API request. I understand that this error can occur the first time a query is run, but I receive the same response even after hitting the API two or three more times.

My question is: do I need to make any changes to the Lighthouse configuration file on the backend?

Apollo Documentation on Persisted Queries
Lighthouse Automated Persisted Queries

Here is my Apollo.js code for reference:

import { ApolloClient, InMemoryCache } from '@apollo/client/core';
import { createUploadLink } from 'apollo-upload-client';
import { provideApolloClient } from '@vue/apollo-composable';
import { setContext } from '@apollo/client/link/context';
import { createPersistedQueryLink } from '@apollo/client/link/persisted-queries';
import { sha256 } from 'crypto-hash';
const httpLink = createUploadLink({
 uri: import.meta.env.VITE_GRAPHQL_API_URL
});
const authLink = setContext((_, { headers }) => {
 const authToken = localStorage.getItem('token');
 return {
 headers: {
 ...headers,
 Authorization: authToken ? `Bearer ${authToken}` : '',
 'X-Requested-With': 'XMLHttpRequest',
 }
 };
});
// Integrate persisted query link
const persistedQueryLink = createPersistedQueryLink({
 sha256,
 useGETForHashedQueries: true // Optional: Use GET requests for persisted queries for CDN caching
});
// Combine links: persistedQueryLink -> authLink -> httpLink
const link = persistedQueryLink.concat(authLink).concat(httpLink);
const apolloClient = new ApolloClient({
 link: link,
 cache: new InMemoryCache(),
 defaultOptions: {
 query: {
 fetchPolicy: 'network-only' // Set the fetch policy to network-only for all queries
 },
 errorPolicy: 'all'
 }
});
// Add Apollo Client instance to global properties
export default {
 install(app) {
 app.use(provideApolloClient, apolloClient);
 app.config.globalProperties.$apollo = apolloClient;
 }
} 

Lighthouse.php config file Code.

<?php
declare(strict_types=1);
return [
 /*
 |--------------------------------------------------------------------------
 | Route Configuration
 |--------------------------------------------------------------------------
 |
 | Controls the HTTP route that your GraphQL server responds to.
 | You may set `route` => false, to disable the default route
 | registration and take full control.
 |
 */
 'route' => [
 /*
 * The URI the endpoint responds to, e.g. mydomain.com/graphql.
 */
 'uri' => '/graphql',
 /*
 * Lighthouse creates a named route for convenient URL generation and redirects.
 */
 'name' => 'graphql',
 /*
 * Beware that middleware defined here runs before the GraphQL execution phase,
 * make sure to return spec-compliant responses in case an error is thrown.
 */
 'middleware' => [
 // Ensures the request is not vulnerable to cross-site request forgery.
 Nuwave\Lighthouse\Http\Middleware\EnsureXHR::class,
 // Always set the `Accept: application/json` header.
 Nuwave\Lighthouse\Http\Middleware\AcceptJson::class,
 // Logs in a user if they are authenticated. In contrast to Laravel's 'auth'
 // middleware, this delegates auth and permission checks to the field level.
 Nuwave\Lighthouse\Http\Middleware\AttemptAuthentication::class,
 // Logs every incoming GraphQL query.
 // Nuwave\Lighthouse\Http\Middleware\LogGraphQLQueries::class,
 ],
 /*
 * The `prefix`, `domain` and `where` configuration options are optional.
 */
 // 'prefix' => '',
 // 'domain' => '',
 // 'where' => [],
 ],
 /*
 |--------------------------------------------------------------------------
 | Authentication Guards
 |--------------------------------------------------------------------------
 |
 | The guards to use for authenticating GraphQL requests, if needed.
 | Used in directives such as `@guard` or the `AttemptAuthentication` middleware.
 | Falls back to the Laravel default if `null`.
 |
 */
 'guards' => ['sanctum'],
 /*
 |--------------------------------------------------------------------------
 | Schema Path
 |--------------------------------------------------------------------------
 |
 | Path to your .graphql schema file.
 | Additional schema files may be imported from within that file.
 |
 */
 'schema_path' => base_path('graphql/schema.graphql'),
 /*
 |--------------------------------------------------------------------------
 | Schema Cache
 |--------------------------------------------------------------------------
 |
 | A large part of schema generation consists of parsing and AST manipulation.
 | This operation is very expensive, so it is highly recommended enabling
 | caching of the final schema to optimize performance of large schemas.
 |
 */
 'schema_cache' => [
 /*
 * Setting to true enables schema caching.
 */
 'enable' => env('LIGHTHOUSE_SCHEMA_CACHE_ENABLE', env('APP_ENV') !== 'local'),
 /*
 * File path to store the lighthouse schema.
 */
 'path' => env('LIGHTHOUSE_SCHEMA_CACHE_PATH', base_path('bootstrap/cache/lighthouse-schema.php')),
 ],
 /*
 |--------------------------------------------------------------------------
 | Cache Directive Tags
 |--------------------------------------------------------------------------
 |
 | Should the `@cache` directive use a tagged cache?
 |
 */
 'cache_directive_tags' => true,
 /*
 |--------------------------------------------------------------------------
 | Query Cache
 |--------------------------------------------------------------------------
 |
 | Caches the result of parsing incoming query strings to boost performance on subsequent requests.
 |
 */
 'query_cache' => [
 /*
 * Setting to true enables query caching.
 */
 'enable' => env('LIGHTHOUSE_QUERY_CACHE_ENABLE', true),
 /*
 * Allows using a specific cache store, uses the app's default if set to null.
 */
 'store' => env('LIGHTHOUSE_QUERY_CACHE_STORE', null),
 /*
 * Duration in seconds the query should remain cached, null means forever.
 */
 'ttl' => env('LIGHTHOUSE_QUERY_CACHE_TTL', 24 * 60 * 60),
 ],
 /*
 |--------------------------------------------------------------------------
 | Namespaces
 |--------------------------------------------------------------------------
 |
 | These are the default namespaces where Lighthouse looks for classes to
 | extend functionality of the schema. You may pass in either a string
 | or an array, they are tried in order and the first match is used.
 |
 */
 'namespaces' => [
 'models' => ['App', 'App\\Models'],
 'queries' => 'App\\GraphQL\\Queries',
 'mutations' => 'App\\GraphQL\\Mutations',
 'subscriptions' => 'App\\GraphQL\\Subscriptions',
 'types' => 'App\\GraphQL\\Types',
 'interfaces' => 'App\\GraphQL\\Interfaces',
 'unions' => 'App\\GraphQL\\Unions',
 'scalars' => 'App\\GraphQL\\Scalars',
 'directives' => 'App\\GraphQL\\Directives',
 'validators' => 'App\\GraphQL\\Validators',
 ],
 /*
 |--------------------------------------------------------------------------
 | Security
 |--------------------------------------------------------------------------
 |
 | Control how Lighthouse handles security related query validation.
 | Read more at https://webonyx.github.io/graphql-php/security/
 |
 */
 'security' => [
 'max_query_complexity' => GraphQL\Validator\Rules\QueryComplexity::DISABLED,
 'max_query_depth' => GraphQL\Validator\Rules\QueryDepth::DISABLED,
 'disable_introspection' => (bool)env('LIGHTHOUSE_SECURITY_DISABLE_INTROSPECTION', env('APP_ENV') == 'production')
 ? GraphQL\Validator\Rules\DisableIntrospection::ENABLED
 : GraphQL\Validator\Rules\DisableIntrospection::DISABLED,
 ],
 /*
 |--------------------------------------------------------------------------
 | Pagination
 |--------------------------------------------------------------------------
 |
 | Set defaults for the pagination features within Lighthouse, such as
 | the @paginate directive, or paginated relation directives.
 |
 */
 'pagination' => [
 /*
 * Allow clients to query paginated lists without specifying the amount of items.
 * Setting this to `null` means clients have to explicitly ask for the count.
 */
 'default_count' => null,
 /*
 * Limit the maximum amount of items that clients can request from paginated lists.
 * Setting this to `null` means the count is unrestricted.
 */
 'max_count' => null,
 ],
 /*
 |--------------------------------------------------------------------------
 | Debug
 |--------------------------------------------------------------------------
 |
 | Control the debug level as described in https://webonyx.github.io/graphql-php/error-handling/
 | Debugging is only applied if the global Laravel debug config is set to true.
 |
 | When you set this value through an environment variable, use the following reference table:
 | 0 => INCLUDE_NONE
 | 1 => INCLUDE_DEBUG_MESSAGE
 | 2 => INCLUDE_TRACE
 | 3 => INCLUDE_TRACE | INCLUDE_DEBUG_MESSAGE
 | 4 => RETHROW_INTERNAL_EXCEPTIONS
 | 5 => RETHROW_INTERNAL_EXCEPTIONS | INCLUDE_DEBUG_MESSAGE
 | 6 => RETHROW_INTERNAL_EXCEPTIONS | INCLUDE_TRACE
 | 7 => RETHROW_INTERNAL_EXCEPTIONS | INCLUDE_TRACE | INCLUDE_DEBUG_MESSAGE
 | 8 => RETHROW_UNSAFE_EXCEPTIONS
 | 9 => RETHROW_UNSAFE_EXCEPTIONS | INCLUDE_DEBUG_MESSAGE
 | 10 => RETHROW_UNSAFE_EXCEPTIONS | INCLUDE_TRACE
 | 11 => RETHROW_UNSAFE_EXCEPTIONS | INCLUDE_TRACE | INCLUDE_DEBUG_MESSAGE
 | 12 => RETHROW_UNSAFE_EXCEPTIONS | RETHROW_INTERNAL_EXCEPTIONS
 | 13 => RETHROW_UNSAFE_EXCEPTIONS | RETHROW_INTERNAL_EXCEPTIONS | INCLUDE_DEBUG_MESSAGE
 | 14 => RETHROW_UNSAFE_EXCEPTIONS | RETHROW_INTERNAL_EXCEPTIONS | INCLUDE_TRACE
 | 15 => RETHROW_UNSAFE_EXCEPTIONS | RETHROW_INTERNAL_EXCEPTIONS | INCLUDE_TRACE | INCLUDE_DEBUG_MESSAGE
 |
 */
 'debug' => env('LIGHTHOUSE_DEBUG', env('APP_DEBUG')
 ? (GraphQL\Error\DebugFlag::INCLUDE_DEBUG_MESSAGE | GraphQL\Error\DebugFlag::INCLUDE_TRACE)
 : GraphQL\Error\DebugFlag::NONE),
 /*
 |--------------------------------------------------------------------------
 | Error Handlers
 |--------------------------------------------------------------------------
 |
 | Register error handlers that receive the Errors that occur during execution
 | and handle them. You may use this to log, filter or format the errors.
 | The classes must implement \Nuwave\Lighthouse\Execution\ErrorHandler
 |
 */
 'error_handlers' => [
 Nuwave\Lighthouse\Execution\AuthenticationErrorHandler::class,
 Nuwave\Lighthouse\Execution\AuthorizationErrorHandler::class,
 Nuwave\Lighthouse\Execution\ValidationErrorHandler::class,
 Nuwave\Lighthouse\Execution\ReportingErrorHandler::class,
 \App\Exceptions\GraphqlErrorHandler::class,
 ],
 /*
 |--------------------------------------------------------------------------
 | Field Middleware
 |--------------------------------------------------------------------------
 |
 | Register global field middleware directives that wrap around every field.
 | Execution happens in the defined order, before other field middleware.
 | The classes must implement \Nuwave\Lighthouse\Support\Contracts\FieldMiddleware
 |
 */
 'field_middleware' => [
 Nuwave\Lighthouse\Schema\Directives\TrimDirective::class,
 Nuwave\Lighthouse\Schema\Directives\ConvertEmptyStringsToNullDirective::class,
 Nuwave\Lighthouse\Schema\Directives\SanitizeDirective::class,
 Nuwave\Lighthouse\Validation\ValidateDirective::class,
 Nuwave\Lighthouse\Schema\Directives\TransformArgsDirective::class,
 Nuwave\Lighthouse\Schema\Directives\SpreadDirective::class,
 Nuwave\Lighthouse\Schema\Directives\RenameArgsDirective::class,
 Nuwave\Lighthouse\Schema\Directives\DropArgsDirective::class,
 ],
 /*
 |--------------------------------------------------------------------------
 | Global ID
 |--------------------------------------------------------------------------
 |
 | The name that is used for the global id field on the Node interface.
 | When creating a Relay compliant server, this must be named "id".
 |
 */
 'global_id_field' => 'id',
 /*
 |--------------------------------------------------------------------------
 | Persisted Queries
 |--------------------------------------------------------------------------
 |
 | Lighthouse supports Automatic Persisted Queries (APQ), compatible with the
 | [Apollo implementation](https://www.apollographql.com/docs/apollo-server/performance/apq).
 | You may set this flag to either process or deny these queries.
 |
 */
 'persisted_queries' => true,
 /*
 |--------------------------------------------------------------------------
 | Transactional Mutations
 |--------------------------------------------------------------------------
 |
 | If set to true, built-in directives that mutate models will be
 | wrapped in a transaction to ensure atomicity.
 |
 */
 'transactional_mutations' => true,
 /*
 |--------------------------------------------------------------------------
 | Mass Assignment Protection
 |--------------------------------------------------------------------------
 |
 | If set to true, mutations will use forceFill() over fill() when populating
 | a model with arguments in mutation directives. Since GraphQL constrains
 | allowed inputs by design, mass assignment protection is not needed.
 |
 */
 'force_fill' => true,
 /*
 |--------------------------------------------------------------------------
 | Batchload Relations
 |--------------------------------------------------------------------------
 |
 | If set to true, relations marked with directives like @hasMany or @belongsTo
 | will be optimized by combining the queries through the BatchLoader.
 |
 */
 'batchload_relations' => true,
 /*
 |--------------------------------------------------------------------------
 | Shortcut Foreign Key Selection
 |--------------------------------------------------------------------------
 |
 | If set to true, Lighthouse will shortcut queries where the client selects only the
 | foreign key pointing to a related model. Only works if the related model's primary
 | key field is called exactly `id` for every type in your schema.
 |
 */
 'shortcut_foreign_key_selection' => false,
 /*
 |--------------------------------------------------------------------------
 | GraphQL Subscriptions
 |--------------------------------------------------------------------------
 |
 | Here you can define GraphQL subscription broadcaster and storage drivers
 | as well their required configuration options.
 |
 */
 'subscriptions' => [
 /*
 * Determines if broadcasts should be queued by default.
 */
 'queue_broadcasts' => env('LIGHTHOUSE_QUEUE_BROADCASTS', true),
 /*
 * Determines the queue to use for broadcasting queue jobs.
 */
 'broadcasts_queue_name' => env('LIGHTHOUSE_BROADCASTS_QUEUE_NAME', null),
 /*
 * Default subscription storage.
 *
 * Any Laravel supported cache driver options are available here.
 */
 'storage' => env('LIGHTHOUSE_SUBSCRIPTION_STORAGE', 'redis'),
 /*
 * Default subscription storage time to live in seconds.
 *
 * Indicates how long a subscription can be active before it's automatically removed from storage.
 * Setting this to `null` means the subscriptions are stored forever. This may cause
 * stale subscriptions to linger indefinitely in case cleanup fails for any reason.
 */
 'storage_ttl' => env('LIGHTHOUSE_SUBSCRIPTION_STORAGE_TTL', null),
 /*
 * Default subscription broadcaster.
 */
 'broadcaster' => env('LIGHTHOUSE_BROADCASTER', 'pusher'),
 /*
 * Subscription broadcasting drivers with config options.
 */
 'broadcasters' => [
 'log' => [
 'driver' => 'log',
 ],
 'pusher' => [
 'driver' => 'pusher',
 'routes' => Nuwave\Lighthouse\Subscriptions\SubscriptionRouter::class . '@pusher',
 'connection' => 'pusher',
 ],
 'echo' => [
 'driver' => 'echo',
 'connection' => env('LIGHTHOUSE_SUBSCRIPTION_REDIS_CONNECTION', 'default'),
 'routes' => Nuwave\Lighthouse\Subscriptions\SubscriptionRouter::class . '@echoRoutes',
 ],
 ],
 /*
 * Should the subscriptions extension be excluded when the response has no subscription channel?
 * This optimizes performance by sending less data, but clients must anticipate this appropriately.
 */
 'exclude_empty' => env('LIGHTHOUSE_SUBSCRIPTION_EXCLUDE_EMPTY', true),
 ],
 /*
 |--------------------------------------------------------------------------
 | Defer
 |--------------------------------------------------------------------------
 |
 | Configuration for the experimental @defer directive support.
 |
 */
 'defer' => [
 /*
 * Maximum number of nested fields that can be deferred in one query.
 * Once reached, remaining fields will be resolved synchronously.
 * 0 means unlimited.
 */
 'max_nested_fields' => 0,
 /*
 * Maximum execution time for deferred queries in milliseconds.
 * Once reached, remaining fields will be resolved synchronously.
 * 0 means unlimited.
 */
 'max_execution_ms' => 0,
 ],
 /*
 |--------------------------------------------------------------------------
 | Apollo Federation
 |--------------------------------------------------------------------------
 |
 | Lighthouse can act as a federated service: https://www.apollographql.com/docs/federation/federation-spec.
 |
 */
 'federation' => [
 /*
 * Location of resolver classes when resolving the `_entities` field.
 */
 'entities_resolver_namespace' => 'App\\GraphQL\\Entities',
 ],
];
You must be logged in to vote

Replies: 0 comments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet
1 participant

AltStyle によって変換されたページ (->オリジナル) /