diff --git a/requirements.txt b/requirements.txt --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -ariadne +ariadne>=0.15 diff --git a/swh/graphql/app.py b/swh/graphql/app.py --- a/swh/graphql/app.py +++ b/swh/graphql/app.py @@ -8,6 +8,7 @@ from pathlib import Path from ariadne import gql, load_schema_from_path, make_executable_schema +from ariadne.validation import cost_directive, cost_validator from .resolvers import resolvers, scalars @@ -19,22 +20,26 @@ ) schema = make_executable_schema( - type_defs, - resolvers.query, - resolvers.origin, - resolvers.visit, - resolvers.visit_status, - resolvers.snapshot, - resolvers.snapshot_branch, - resolvers.revision, - resolvers.release, - resolvers.directory, - resolvers.directory_entry, - resolvers.branch_target, - resolvers.release_target, - resolvers.directory_entry_target, - resolvers.binary_string, - scalars.id_scalar, - scalars.datetime_scalar, - scalars.swhid_scalar, + [type_defs, cost_directive], + [ + resolvers.query, + resolvers.origin, + resolvers.visit, + resolvers.visit_status, + resolvers.snapshot, + resolvers.snapshot_branch, + resolvers.revision, + resolvers.release, + resolvers.directory, + resolvers.directory_entry, + resolvers.branch_target, + resolvers.release_target, + resolvers.directory_entry_target, + resolvers.binary_string, + scalars.id_scalar, + scalars.datetime_scalar, + scalars.swhid_scalar, + ], ) + +validation_rules = [cost_validator(maximum_cost=200)] diff --git a/swh/graphql/schema/schema.graphql b/swh/graphql/schema/schema.graphql --- a/swh/graphql/schema/schema.graphql +++ b/swh/graphql/schema/schema.graphql @@ -127,12 +127,12 @@ Returns the page after this cursor """ after: String - ): VisitConnection! + ): VisitConnection! @cost(complexity: 2) """ Latest visit object for the origin """ - latestVisit: Visit + latestVisit: Visit @cost(complexity: 1) """ Connection to all the snapshots for the origin @@ -147,7 +147,7 @@ Returns the page after this cursor """ after: String - ): SnapshotConnection + ): SnapshotConnection @cost(complexity: 2) } """ @@ -227,12 +227,12 @@ Returns the page after this cursor """ after: String - ): VisitStatusConnection + ): VisitStatusConnection @cost(complexity: 2) """ Latest status object for the Visit """ - latestStatus: VisitStatus + latestStatus: VisitStatus @cost(complexity: 1) } """ @@ -292,7 +292,7 @@ """ Snapshot object """ - snapshot: Snapshot + snapshot: Snapshot @cost(complexity: 1) """ Type of the origin visited. Eg: git/hg/svn/tar/deb @@ -377,7 +377,7 @@ Filter by branch name """ nameInclude: String - ): BranchConnection + ): BranchConnection @cost(complexity: 2) } """ @@ -474,7 +474,7 @@ """ Branch target object """ - target: BranchTarget + target: BranchTarget @cost(complexity: 1) } """ @@ -557,7 +557,7 @@ """ The unique directory object that revision points to """ - directory: Directory + directory: Directory @cost(complexity: 1) """ Connection to all the parents of the revision @@ -572,7 +572,7 @@ Returns the page after this cursor """ after: String - ): RevisionConnection + ): RevisionConnection @cost(complexity: 2) """ Connection to all the revisions heading to this one @@ -588,7 +588,7 @@ Returns the page after the cursor """ after: String - ): RevisionConnection + ): RevisionConnection @cost(complexity: 2) } """ @@ -647,7 +647,7 @@ """ Release target object """ - target: ReleaseTarget + target: ReleaseTarget @cost(complexity: 1) } """ @@ -721,7 +721,7 @@ """ Directory entry target object """ - target: DirectoryEntryTarget + target: DirectoryEntryTarget @cost(complexity: 1) } """ @@ -751,7 +751,7 @@ Returns the page after this cursor """ after: String - ): DirectoryEntryConnection + ): DirectoryEntryConnection @cost(complexity: 2) } """ @@ -817,7 +817,7 @@ URL of the Origin """ url: String! - ): Origin + ): Origin @cost(complexity: 1) """ Get a Connection to all the origins @@ -837,7 +837,7 @@ Filter origins with a URL pattern """ urlPattern: String - ): OriginConnection + ): OriginConnection @cost(complexity: 2) """ Get the visit object with an origin URL and a visit id @@ -852,7 +852,7 @@ Visit id to get """ visitId: Int! - ): Visit + ): Visit @cost(complexity: 1) """ Get the snapshot with a SWHID @@ -862,7 +862,7 @@ SWHID of the snapshot object """ swhid: SWHID! - ): Snapshot + ): Snapshot @cost(complexity: 1) """ Get the revision with a SWHID @@ -872,7 +872,7 @@ SWHID of the revision object """ swhid: SWHID! - ): Revision + ): Revision @cost(complexity: 1) """ Get the release with a SWHID @@ -882,7 +882,7 @@ SWHID of the release object """ swhid: SWHID! - ): Release + ): Release @cost(complexity: 1) """ Get the directory with a SWHID @@ -892,7 +892,7 @@ SWHID of the directory object """ swhid: SWHID! - ): Directory + ): Directory @cost(complexity: 1) """ Get the content with a SWHID @@ -902,5 +902,5 @@ SWHID of the content object """ swhid: SWHID! - ): Content + ): Content @cost(complexity: 1) } diff --git a/swh/graphql/server.py b/swh/graphql/server.py --- a/swh/graphql/server.py +++ b/swh/graphql/server.py @@ -55,7 +55,7 @@ configuration path to load. """ - from .app import schema + from .app import schema, validation_rules global graphql_cfg @@ -67,9 +67,9 @@ if server_type == "asgi": from ariadne.asgi import GraphQL - application = GraphQL(schema) + application = GraphQL(schema, validation_rules=validation_rules) else: from ariadne.wsgi import GraphQL - application = GraphQL(schema) + application = GraphQL(schema, validation_rules=validation_rules) return application