From dfe7b473c0a207b4c481aeb1a061f7ebb4cae01a Mon Sep 17 00:00:00 2001 From: erdar2 Date: Wed, 22 Dec 2021 12:21:51 +0100 Subject: [PATCH] feat: GraphQL integration, and api --- app/GraphQL/Queries/SearchData.php | 19 ++ composer.json | 3 +- config/lighthouse.php | 465 +++++++++++++++++++++++++++++ graphql/schema.graphql | 21 ++ 4 files changed, 507 insertions(+), 1 deletion(-) create mode 100644 app/GraphQL/Queries/SearchData.php create mode 100644 config/lighthouse.php create mode 100644 graphql/schema.graphql diff --git a/app/GraphQL/Queries/SearchData.php b/app/GraphQL/Queries/SearchData.php new file mode 100644 index 0000000..f9e4976 --- /dev/null +++ b/app/GraphQL/Queries/SearchData.php @@ -0,0 +1,19 @@ + $args + */ + public function __invoke($_, array $args) + { + $endDate = isset($args["endDate"]) ? $args["endDate"]->endOfDay() : Carbon::now(); + $data = CovidData::where('created_at','>=',$args["beginDate"])->where('created_at','<=',$endDate)->orderBy('created_at')->get(); + return $data; + } +} diff --git a/composer.json b/composer.json index 04d1ddb..1887ca3 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,8 @@ "guzzlehttp/guzzle": "^7.4", "laravel/framework": "^8.65", "laravel/tinker": "^2.5", - "laravel/ui": "^3.4" + "laravel/ui": "^3.4", + "nuwave/lighthouse": "^5.31" }, "require-dev": { "facade/ignition": "^2.5", diff --git a/config/lighthouse.php b/config/lighthouse.php new file mode 100644 index 0000000..3a4c3d3 --- /dev/null +++ b/config/lighthouse.php @@ -0,0 +1,465 @@ + 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' => [ + \Nuwave\Lighthouse\Support\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\Support\Http\Middleware\AttemptAuthentication::class, + + // Logs every incoming GraphQL query. + // \Nuwave\Lighthouse\Support\Http\Middleware\LogGraphQLQueries::class, + ], + + /* + * The `prefix` and `domain` configuration options are optional. + */ + //'prefix' => '', + //'domain' => '', + ], + + /* + |-------------------------------------------------------------------------- + | Authentication Guard + |-------------------------------------------------------------------------- + | + | The guard 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 the defined guard is either `null` or not found. + | + */ + + 'guard' => 'api', + + /* + |-------------------------------------------------------------------------- + | Schema Location + |-------------------------------------------------------------------------- + | + | Path to your .graphql schema file. + | Additional schema files may be imported from within that file. + | + */ + + 'schema' => [ + 'register' => 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 to enable + | caching of the final schema to optimize performance of large schemas. + | + */ + + 'cache' => [ + /* + * Setting to true enables schema caching. + */ + 'enable' => env('LIGHTHOUSE_CACHE_ENABLE', 'local' !== env('APP_ENV')), + + /* + * Allowed values: + * - 1: uses the store, key and ttl config values to store the schema as a string in the given cache store. + * - 2: uses the path config value to store the schema in a PHP file allowing OPcache to pick it up. + */ + 'version' => env('LIGHTHOUSE_CACHE_VERSION', 1), + + /* + * Allows using a specific cache store, uses the app's default if set to null. + * Only relevant if version is set to 1. + */ + 'store' => env('LIGHTHOUSE_CACHE_STORE', null), + + /* + * The name of the cache item for the schema cache. + * Only relevant if version is set to 1. + */ + 'key' => env('LIGHTHOUSE_CACHE_KEY', 'lighthouse-schema'), + + /* + * Duration in seconds the schema should remain cached, null means forever. + * Only relevant if version is set to 1. + */ + 'ttl' => env('LIGHTHOUSE_CACHE_TTL', null), + + /* + * File path to store the lighthouse schema. + * Only relevant if version is set to 2. + */ + 'path' => env('LIGHTHOUSE_CACHE_PATH', base_path('bootstrap/cache/lighthouse-schema.php')), + ], + + /* + |-------------------------------------------------------------------------- + | 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', + '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' => \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', \GraphQL\Error\DebugFlag::INCLUDE_DEBUG_MESSAGE | \GraphQL\Error\DebugFlag::INCLUDE_TRACE), + + /* + |-------------------------------------------------------------------------- + | 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\ExtensionErrorHandler::class, + \Nuwave\Lighthouse\Execution\ReportingErrorHandler::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\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, + ], + + /* + |-------------------------------------------------------------------------- + | 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', + + /* + |-------------------------------------------------------------------------- + | Batched Queries + |-------------------------------------------------------------------------- + | + | GraphQL query batching means sending multiple queries to the server in one request, + | You may set this flag to either process or deny batched queries. + | + */ + + 'batched_queries' => true, + + /* + |-------------------------------------------------------------------------- + | Transactional Mutations + |-------------------------------------------------------------------------- + | + | If set to true, mutations such as @create or @update 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, + + /* + |-------------------------------------------------------------------------- + | Non-Null Pagination Results + |-------------------------------------------------------------------------- + | + | If set to true, the generated result type of paginated lists will be marked + | as non-nullable. This is generally more convenient for clients, but will + | cause validation errors to bubble further up in the result. + | + | This setting will be removed and always behave as if it were true in v6. + | + */ + + 'non_null_pagination_results' => false, + + /* + |-------------------------------------------------------------------------- + | Unbox BenSampo\Enum\Enum instances + |-------------------------------------------------------------------------- + | + | If set to true, Lighthouse will extract the internal $value from instances of + | BenSampo\Enum\Enum before passing it to ArgBuilderDirective::handleBuilder(). + | + | This setting will be removed and always behave as if it were false in v6. + | + | It is only here to preserve compatibility, e.g. when expecting the internal + | value to be passed to a scope when using @scope, but not needed due to Laravel + | calling the Enum's __toString() method automagically when used in a query. + | + */ + + 'unbox_bensampo_enum_enum_instances' => true, + + /* + |-------------------------------------------------------------------------- + | 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', + ], + ], + + /* + * Controls the format of the extensions response. + * Allowed values: 1, 2 + */ + 'version' => env('LIGHTHOUSE_SUBSCRIPTION_VERSION', 1), + + /* + * 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. + * Will default to true in v6 and be removed in v7. + */ + 'exclude_empty' => env('LIGHTHOUSE_SUBSCRIPTION_EXCLUDE_EMPTY', false), + ], + + /* + |-------------------------------------------------------------------------- + | 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', + ], +]; diff --git a/graphql/schema.graphql b/graphql/schema.graphql new file mode 100644 index 0000000..92efc2d --- /dev/null +++ b/graphql/schema.graphql @@ -0,0 +1,21 @@ +"A date string with format `Y-m-d`, e.g. `2011-05-23`." +scalar Date @scalar(class: "Nuwave\\Lighthouse\\Schema\\Types\\Scalars\\Date") + +"A datetime string with format `Y-m-d H:i:s`, e.g. `2018-05-23 13:43:32`." +scalar DateTime @scalar(class: "Nuwave\\Lighthouse\\Schema\\Types\\Scalars\\DateTime") + +type Query { + all_data: [CovidData!]! + data(id: ID @eq): CovidData @find + searchData(beginDate: Date!, endDate: Date) : [CovidData!]! +} + +type CovidData { + id: ID! + infected: Int + deceased: Int + recovered: Int + quarantined: Int + tested: Int + created_at: DateTime! +}