From ee7c7b16729c0eef01c2957e5532b4bfd3ee5e4f Mon Sep 17 00:00:00 2001 From: Auke Booij Date: Mon, 27 Apr 2020 17:07:03 +0200 Subject: [PATCH 1/2] server: allow computed fields to have access to Hasura's session variables (fix #3846) (#4486) * Allow computed fields to have access to Hasura's session variables * Inform about session args for computed fields in changelog and docs * Add tests for session arguments for computed fields (and the respective errors) Co-authored-by: Tirumarai Selvan Co-authored-by: Marion Schleifer Co-authored-by: Rakesh Emmadi <12475069+rakeshkky@users.noreply.github.com> --- CHANGELOG.md | 30 +++++++ .../schema-metadata-api/computed-field.rst | 6 ++ .../graphql/manual/schema/computed-fields.rst | 70 +++++++++++++++ .../src-lib/Hasura/GraphQL/Resolve/Select.hs | 25 ++++-- server/src-lib/Hasura/GraphQL/Schema.hs | 2 +- .../src-lib/Hasura/RQL/DDL/ComputedField.hs | 66 +++++++++++--- .../src-lib/Hasura/RQL/DML/Select/Internal.hs | 1 + server/src-lib/Hasura/RQL/DML/Select/Types.hs | 1 + .../src-lib/Hasura/RQL/Types/ComputedField.hs | 21 ++++- .../v1/computed_fields/add_and_drop.yaml | 29 +++++++ .../add_computed_field_errors.yaml | 87 +++++++++++++++++-- .../queries/v1/computed_fields/setup.yaml | 5 ++ .../queries/v1/computed_fields/teardown.yaml | 1 + .../queries/v1/metadata/export_metadata.yaml | 6 ++ .../tests-py/queries/v1/metadata/setup.yaml | 17 ++++ .../queries/v1/metadata/teardown.yaml | 2 +- 16 files changed, 334 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be5f63c2f12..2d0158c914d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,36 @@ ## Next release +### Allow access to session variables by computed fields (fix #3846) + +Sometimes it is useful for computed fields to have access to the Hasura session variables directly. For example, suppose you want to fetch some articles but also get related user info, say `likedByMe`. Now, you can define a function like: + +``` +CREATE OR REPLACE FUNCTION article_liked(article_row article, hasura_session json) +RETURNS boolean AS $$ + SELECT EXISTS ( + SELECT 1 + FROM liked_article A + WHERE A.user_id = hasura_session ->> 'x-hasura-user-id' AND A.article_id = article_row.id + ); +$$ LANGUAGE sql STABLE; +``` +and make a query like: + +``` +query { + articles { + title + content + likedByMe + } +} +``` + +Support for this is now added through the `add_computed_field` API. + +Read more about the session argument for computed fields in the [docs](https://hasura.io/docs/1.0/graphql/manual/api-reference/schema-metadata-api/computed-field.html). + ### Bug fixes and improvements - console: make GraphiQL Explorer taking the whole viewport diff --git a/docs/graphql/manual/api-reference/schema-metadata-api/computed-field.rst b/docs/graphql/manual/api-reference/schema-metadata-api/computed-field.rst index a3473576526..a6a2d9b0e02 100644 --- a/docs/graphql/manual/api-reference/schema-metadata-api/computed-field.rst +++ b/docs/graphql/manual/api-reference/schema-metadata-api/computed-field.rst @@ -105,6 +105,12 @@ ComputedFieldDefinition - String - Name of the argument which accepts a table row type. If omitted, the first argument is considered a table argument + * - session_argument + - false + - String + - Name of the argument which accepts the Hasura session object as + a JSON/JSONB value. If omitted, the Hasura session object is + not passed to the function .. _drop_computed_field: diff --git a/docs/graphql/manual/schema/computed-fields.rst b/docs/graphql/manual/schema/computed-fields.rst index 37e9ee7e96a..59ecbcafc3c 100644 --- a/docs/graphql/manual/schema/computed-fields.rst +++ b/docs/graphql/manual/schema/computed-fields.rst @@ -195,6 +195,76 @@ Computed fields permissions - For **table computed fields**, the permissions set on the return table are respected. +Accessing Hasura session variables in computed fields +----------------------------------------------------- + +It can be useful to have access to the session variable from the SQL function defining a computed field. For instance, suppose we want to record which users have liked which articles. We can do so using a table ``article_likes`` that specifies a many-to-many relationship between ``article`` and ``user``. In such a case it can be useful to know if the current user has liked a specific article, and this information can be exposed as a *Boolean* computed field on ``article``. + +Use the :ref:`add_computed_field` API to add a function, and specify the name of the argument taking a session argument in ``session_argument``. The session argument is a JSON object where keys are session variable names (in lower case) and values are strings. Use the ``->>`` JSON operator to fetch the value of a session variable as shown in the following example. + +.. code-block:: plpgsql + + -- 'hasura_session' will be the session argument + CREATE OR REPLACE FUNCTION article_liked_by_user(article_row article, hasura_session json) + RETURNS boolean AS $$ + SELECT EXISTS ( + SELECT 1 + FROM article_likes A + WHERE A.user_id = hasura_session ->> 'x-hasura-user-id' AND A.article_id = article_row.id + ); + $$ LANGUAGE sql STABLE; + +.. code-block:: http + + POST /v1/query HTTP/1.1 + Content-Type: application/json + X-Hasura-Role: admin + + { + "type":"add_computed_field", + "args":{ + "table":{ + "name":"article", + "schema":"public" + }, + "name":"liked_by_user", + "definition":{ + "function":{ + "name":"article_liked_by_user", + "schema":"public" + }, + "table_argument":"article_row", + "session_argument":"hasura_session" + } + } + } + +.. graphiql:: + :view_only: + :query: + query { + article(where: {id: {_eq: 3}}) { + id + liked_by_user + } + } + :response: + { + "data": { + "article": [ + { + "id": "3", + "liked_by_user": true + } + ] + } + } + +.. note:: + + The specified session argument is not included in the ``_args`` input object in the GraphQL schema. + + Computed fields vs. Postgres generated columns ---------------------------------------------- diff --git a/server/src-lib/Hasura/GraphQL/Resolve/Select.hs b/server/src-lib/Hasura/GraphQL/Resolve/Select.hs index a3519cad4f8..5695b4b6fe8 100644 --- a/server/src-lib/Hasura/GraphQL/Resolve/Select.hs +++ b/server/src-lib/Hasura/GraphQL/Resolve/Select.hs @@ -62,7 +62,7 @@ resolveComputedField => ComputedField -> Field -> m (RS.ComputedFieldSel UnresolvedVal) resolveComputedField computedField fld = fieldAsPath fld $ do funcArgs <- parseFunctionArgs argSeq argFn $ Map.lookup "args" $ _fArguments fld - let argsWithTableArgument = withTableArgument funcArgs + let argsWithTableArgument = withTableAndSessionArgument funcArgs case fieldType of CFTScalar scalarTy -> do colOpM <- argsToColOp $ _fArguments fld @@ -73,16 +73,25 @@ resolveComputedField computedField fld = fieldAsPath fld $ do RS.CFSTable RS.JASMultipleRows <$> fromField functionFrom cols permFilter permLimit fld where ComputedField _ function argSeq fieldType = computedField - ComputedFieldFunction qf _ tableArg _ = function + ComputedFieldFunction qf _ tableArg sessionArg _ = function + argFn :: FunctionArgItem -> InputFunctionArgument argFn = IFAUnknown - withTableArgument resolvedArgs = + withTableAndSessionArgument :: RS.FunctionArgsExpG UnresolvedVal + -> RS.FunctionArgsExpTableRow UnresolvedVal + withTableAndSessionArgument resolvedArgs = let argsExp@(RS.FunctionArgsExp positional named) = RS.AEInput <$> resolvedArgs tableRowArg = RS.AETableRow Nothing - in case tableArg of - FTAFirst -> - RS.FunctionArgsExp (tableRowArg:positional) named - FTANamed argName index -> - RS.insertFunctionArg argName index tableRowArg argsExp + withTable = case tableArg of + FTAFirst -> + RS.FunctionArgsExp (tableRowArg:positional) named + FTANamed argName index -> + RS.insertFunctionArg argName index tableRowArg argsExp + sessionArgVal = RS.AESession UVSession + alsoWithSession = case sessionArg of + Nothing -> withTable + Just (FunctionSessionArgument argName index) -> + RS.insertFunctionArg argName index sessionArgVal withTable + in alsoWithSession processTableSelectionSet :: ( MonadReusability m, MonadError QErr m, MonadReader r m, Has FieldMap r diff --git a/server/src-lib/Hasura/GraphQL/Schema.hs b/server/src-lib/Hasura/GraphQL/Schema.hs index 71099e8b533..c91153b7540 100644 --- a/server/src-lib/Hasura/GraphQL/Schema.hs +++ b/server/src-lib/Hasura/GraphQL/Schema.hs @@ -315,7 +315,7 @@ mkGCtxRole' tn descM insPermM selPermM updColsM delPermM pkeyCols constraints vi -- computed fields' function args input objects and scalar types mkComputedFieldRequiredTypes computedFieldInfo = - let ComputedFieldFunction qf inputArgs _ _ = _cfFunction computedFieldInfo + let ComputedFieldFunction qf inputArgs _ _ _ = _cfFunction computedFieldInfo scalarArgs = map (_qptName . faType) $ toList inputArgs in (, scalarArgs) <$> mkFuncArgsInp qf inputArgs diff --git a/server/src-lib/Hasura/RQL/DDL/ComputedField.hs b/server/src-lib/Hasura/RQL/DDL/ComputedField.hs index a0578c317ab..47c9a238a31 100644 --- a/server/src-lib/Hasura/RQL/DDL/ComputedField.hs +++ b/server/src-lib/Hasura/RQL/DDL/ComputedField.hs @@ -36,12 +36,13 @@ import qualified Language.GraphQL.Draft.Syntax as G data ComputedFieldDefinition = ComputedFieldDefinition - { _cfdFunction :: !QualifiedFunction - , _cfdTableArgument :: !(Maybe FunctionArgName) + { _cfdFunction :: !QualifiedFunction + , _cfdTableArgument :: !(Maybe FunctionArgName) + , _cfdSessionArgument :: !(Maybe FunctionArgName) } deriving (Show, Eq, Lift, Generic) instance NFData ComputedFieldDefinition instance Cacheable ComputedFieldDefinition -$(deriveJSON (aesonDrop 4 snakeCase) ''ComputedFieldDefinition) +$(deriveJSON (aesonDrop 4 snakeCase){omitNothingFields = True} ''ComputedFieldDefinition) data AddComputedField = AddComputedField @@ -64,6 +65,7 @@ runAddComputedField q = do data ComputedFieldValidateError = CFVENotValidGraphQLName !ComputedFieldName | CFVEInvalidTableArgument !InvalidTableArgument + | CFVEInvalidSessionArgument !InvalidSessionArgument | CFVENotBaseReturnType !PGScalarType | CFVEReturnTableNotFound !QualifiedTable | CFVENoInputArguments @@ -76,17 +78,26 @@ data InvalidTableArgument | ITANotTable !QualifiedTable !FunctionTableArgument deriving (Show, Eq) +data InvalidSessionArgument + = ISANotFound !FunctionArgName + | ISANotJSON !FunctionSessionArgument + deriving (Show, Eq) + showError :: QualifiedFunction -> ComputedFieldValidateError -> Text showError qf = \case CFVENotValidGraphQLName computedField -> computedField <<> " is not valid GraphQL name" CFVEInvalidTableArgument (ITANotFound argName) -> - argName <<> " is not an input argument of " <> qf <<> " function" + argName <<> " is not an input argument of the function " <>> qf CFVEInvalidTableArgument (ITANotComposite functionArg) -> showFunctionTableArgument functionArg <> " is not COMPOSITE type" CFVEInvalidTableArgument (ITANotTable ty functionArg) -> showFunctionTableArgument functionArg <> " of type " <> ty <<> " is not the table to which the computed field is being added" + CFVEInvalidSessionArgument (ISANotFound argName) -> + argName <<> " is not an input argument of the function " <>> qf + CFVEInvalidSessionArgument (ISANotJSON functionArg) -> + showFunctionSessionArgument functionArg <> " is not of type JSON" CFVENotBaseReturnType scalarType -> "the function " <> qf <<> " returning type " <> toSQLTxt scalarType <> " is not a BASE type" @@ -101,6 +112,8 @@ showError qf = \case showFunctionTableArgument = \case FTAFirst -> "first argument of the function " <>> qf FTANamed argName _ -> argName <<> " argument of the function " <>> qf + showFunctionSessionArgument = \case + FunctionSessionArgument argName _ -> argName <<> " argument of the function " <>> qf addComputedFieldP2Setup :: (QErrM m) @@ -116,7 +129,7 @@ addComputedFieldP2Setup trackedTables table computedField definition rawFunction either (throw400 NotSupported . showErrors) pure =<< MV.runValidateT (mkComputedFieldInfo) where inputArgNames = rfiInputArgNames rawFunctionInfo - ComputedFieldDefinition function maybeTableArg = definition + ComputedFieldDefinition function maybeTableArg maybeSessionArg = definition functionReturnType = QualifiedPGType (rfiReturnTypeSchema rawFunctionInfo) (rfiReturnTypeName rawFunctionInfo) (rfiReturnTypeType rawFunctionInfo) @@ -166,10 +179,21 @@ addComputedFieldP2Setup trackedTables table computedField definition rawFunction validateTableArgumentType FTAFirst $ faType firstArg pure FTAFirst + maybePGSessionArg <- sequence $ do + argName <- maybeSessionArg + return $ case findWithIndex (maybe False (argName ==) . faName) inputArgs of + Just (sessionArg, index) -> do + let functionSessionArg = FunctionSessionArgument argName index + validateSessionArgumentType functionSessionArg $ faType sessionArg + pure functionSessionArg + Nothing -> + MV.refute $ pure $ CFVEInvalidSessionArgument $ ISANotFound argName - let inputArgSeq = Seq.fromList $ dropTableArgument tableArgument inputArgs + + let inputArgSeq = Seq.fromList $ dropTableAndSessionArgument tableArgument + maybePGSessionArg inputArgs computedFieldFunction = - ComputedFieldFunction function inputArgSeq tableArgument $ + ComputedFieldFunction function inputArgSeq tableArgument maybePGSessionArg $ rfiDescription rawFunctionInfo pure $ ComputedFieldInfo computedField computedFieldFunction returnType comment @@ -185,6 +209,14 @@ addComputedFieldP2Setup trackedTables table computedField definition rawFunction unless (table == typeTable) $ MV.dispute $ pure $ CFVEInvalidTableArgument $ ITANotTable typeTable tableArg + validateSessionArgumentType :: (MV.MonadValidate [ComputedFieldValidateError] m) + => FunctionSessionArgument + -> QualifiedPGType + -> m () + validateSessionArgumentType sessionArg qpt = do + when (not . isJSONType . _qptName $ qpt) $ + MV.dispute $ pure $ CFVEInvalidSessionArgument $ ISANotJSON sessionArg + showErrors :: [ComputedFieldValidateError] -> Text showErrors allErrors = "the computed field " <> computedField <<> " cannot be added to table " @@ -192,12 +224,20 @@ addComputedFieldP2Setup trackedTables table computedField definition rawFunction where reasonMessage = makeReasonMessage allErrors (showError function) - dropTableArgument :: FunctionTableArgument -> [FunctionArg] -> [FunctionArg] - dropTableArgument tableArg inputArgs = - case tableArg of - FTAFirst -> tail inputArgs - FTANamed argName _ -> - filter ((/=) (Just argName) . faName) inputArgs + dropTableAndSessionArgument :: FunctionTableArgument + -> Maybe FunctionSessionArgument -> [FunctionArg] + -> [FunctionArg] + dropTableAndSessionArgument tableArg sessionArg inputArgs = + let withoutTable = case tableArg of + FTAFirst -> tail inputArgs + FTANamed argName _ -> + filter ((/=) (Just argName) . faName) inputArgs + alsoWithoutSession = case sessionArg of + Nothing -> withoutTable + Just (FunctionSessionArgument name _) -> + filter ((/=) (Just name) . faName) withoutTable + in alsoWithoutSession + addComputedFieldToCatalog :: MonadTx m diff --git a/server/src-lib/Hasura/RQL/DML/Select/Internal.hs b/server/src-lib/Hasura/RQL/DML/Select/Internal.hs index c6cd5b60121..db7c659bb21 100644 --- a/server/src-lib/Hasura/RQL/DML/Select/Internal.hs +++ b/server/src-lib/Hasura/RQL/DML/Select/Internal.hs @@ -191,6 +191,7 @@ fromTableRowArgs pfx = toFunctionArgs . fmap toSQLExp S.FunctionArgs positional named toSQLExp (AETableRow Nothing) = S.SERowIden $ mkBaseTableAls pfx toSQLExp (AETableRow (Just acc)) = S.mkQIdenExp (mkBaseTableAls pfx) acc + toSQLExp (AESession s) = s toSQLExp (AEInput s) = s -- posttgres ignores anything beyond 63 chars for an iden diff --git a/server/src-lib/Hasura/RQL/DML/Select/Types.hs b/server/src-lib/Hasura/RQL/DML/Select/Types.hs index 8dc04963043..9202866e0b1 100644 --- a/server/src-lib/Hasura/RQL/DML/Select/Types.hs +++ b/server/src-lib/Hasura/RQL/DML/Select/Types.hs @@ -261,6 +261,7 @@ type TableAggFlds = TableAggFldsG S.SQLExp data ArgumentExp a = AETableRow !(Maybe Iden) -- ^ table row accessor + | AESession !a -- ^ JSON/JSONB hasura session variable object | AEInput !a deriving (Show, Eq, Functor, Foldable, Traversable) diff --git a/server/src-lib/Hasura/RQL/Types/ComputedField.hs b/server/src-lib/Hasura/RQL/Types/ComputedField.hs index caf270abfd3..1deea120613 100644 --- a/server/src-lib/Hasura/RQL/Types/ComputedField.hs +++ b/server/src-lib/Hasura/RQL/Types/ComputedField.hs @@ -44,6 +44,18 @@ instance ToJSON FunctionTableArgument where toJSON FTAFirst = String "first_argument" toJSON (FTANamed argName _) = object ["name" .= argName] +-- | The session argument, which passes Hasura session variables to a +-- SQL function as a JSON object. +data FunctionSessionArgument + = FunctionSessionArgument + !FunctionArgName -- ^ The argument name + !Int -- ^ The ordinal position in the function input parameters + deriving (Show, Eq, Generic) +instance Cacheable FunctionSessionArgument + +instance ToJSON FunctionSessionArgument where + toJSON (FunctionSessionArgument argName _) = toJSON argName + data ComputedFieldReturn = CFRScalar !PGScalarType | CFRSetofTable !QualifiedTable @@ -58,10 +70,11 @@ $(makePrisms ''ComputedFieldReturn) data ComputedFieldFunction = ComputedFieldFunction - { _cffName :: !QualifiedFunction - , _cffInputArgs :: !(Seq.Seq FunctionArg) - , _cffTableArgument :: !FunctionTableArgument - , _cffDescription :: !(Maybe PGDescription) + { _cffName :: !QualifiedFunction + , _cffInputArgs :: !(Seq.Seq FunctionArg) + , _cffTableArgument :: !FunctionTableArgument + , _cffSessionArgument :: !(Maybe FunctionSessionArgument) + , _cffDescription :: !(Maybe PGDescription) } deriving (Show, Eq, Generic) instance Cacheable ComputedFieldFunction $(deriveToJSON (aesonDrop 4 snakeCase) ''ComputedFieldFunction) diff --git a/server/tests-py/queries/v1/computed_fields/add_and_drop.yaml b/server/tests-py/queries/v1/computed_fields/add_and_drop.yaml index 0f22397bf75..b67acc13c1d 100644 --- a/server/tests-py/queries/v1/computed_fields/add_and_drop.yaml +++ b/server/tests-py/queries/v1/computed_fields/add_and_drop.yaml @@ -48,3 +48,32 @@ name: get_articles response: message: success + +- description: Add a computed field, passing the Hasura session argument + url: /v1/query + status: 200 + query: + type: add_computed_field + args: + table: author + name: test_session + definition: + function: test_session + session_argument: session + response: + message: success + +- description: obtain the session variable via computed fields + url: /v1/graphql + status: 200 + query: + query: | + query { + author_by_pk(id: 1) { + test_session(args:{key:"x-hasura-role"}) + } + } + response: + data: + author_by_pk: + test_session: admin diff --git a/server/tests-py/queries/v1/computed_fields/add_computed_field_errors.yaml b/server/tests-py/queries/v1/computed_fields/add_computed_field_errors.yaml index 39fa5d96ba1..eebbc08b3fc 100644 --- a/server/tests-py/queries/v1/computed_fields/add_computed_field_errors.yaml +++ b/server/tests-py/queries/v1/computed_fields/add_computed_field_errors.yaml @@ -30,7 +30,6 @@ function: schema: public name: full_name - table_argument: name: first_name comment: table: @@ -41,6 +40,7 @@ path: $.args error: field definition conflicts with postgres column code: constraint-violation + - description: Try adding computed field with invalid function url: /v1/query status: 400 @@ -58,7 +58,6 @@ function: schema: public name: random_function - table_argument: name: full_name comment: table: @@ -71,6 +70,7 @@ error: 'in table "author": in computed field "full_name": no such function exists in postgres : "random_function"' code: constraint-violation + - description: Try adding computed field with invalid table argument name url: /v1/query status: 400 @@ -97,13 +97,14 @@ name: author reason: 'in table "author": in computed field "full_name": the computed field "full_name" cannot be added to table "author" because "random" is not an input - argument of "full_name" function' + argument of the function "full_name"' type: computed_field path: $.args error: 'in table "author": in computed field "full_name": the computed field "full_name" cannot be added to table "author" because "random" is not an input argument - of "full_name" function' + of the function "full_name"' code: constraint-violation + - description: Try adding computed field with a volatile function url: /v1/query status: 400 @@ -132,15 +133,16 @@ \ field \"get_articles\" cannot be added to table \"author\" for the following\ \ reasons:\n • the function \"fetch_articles_volatile\" is of type VOLATILE;\ \ cannot be added as a computed field\n • \"random\" is not an input argument\ - \ of \"fetch_articles_volatile\" function\n" + \ of the function \"fetch_articles_volatile\"\n" type: computed_field path: $.args error: "in table \"author\": in computed field \"get_articles\": the computed\ \ field \"get_articles\" cannot be added to table \"author\" for the following\ \ reasons:\n • the function \"fetch_articles_volatile\" is of type VOLATILE;\ \ cannot be added as a computed field\n • \"random\" is not an input argument\ - \ of \"fetch_articles_volatile\" function\n" + \ of the function \"fetch_articles_volatile\"\n" code: constraint-violation + - description: Try adding a computed field with a function with no input arguments url: /v1/query status: 400 @@ -158,7 +160,6 @@ function: schema: public name: hello_world - table_argument: name: hello_world comment: table: @@ -173,6 +174,7 @@ "hello_world" cannot be added to table "author" because the function "hello_world" has no input arguments' code: constraint-violation + - description: Try adding a computed field with first argument as table argument url: /v1/query status: 400 @@ -190,7 +192,6 @@ function: schema: public name: fetch_articles - table_argument: name: get_articles comment: table: @@ -209,3 +210,73 @@ \ type\n • first argument of the function \"fetch_articles\" of type \"pg_catalog.text\"\ \ is not the table to which the computed field is being added\n" code: constraint-violation + +- description: Try adding a computed field with an invalid session argument name + url: /v1/query + status: 400 + query: + type: add_computed_field + args: + table: author + name: full_name + definition: + function: full_name + session_argument: random + response: + internal: + - definition: + definition: + function: + schema: public + name: full_name + session_argument: random + name: full_name + comment: + table: + schema: public + name: author + reason: 'in table "author": in computed field "full_name": the computed field + "full_name" cannot be added to table "author" because "random" is not an input + argument of the function "full_name"' + type: computed_field + path: $.args + error: 'in table "author": in computed field "full_name": the computed field "full_name" + cannot be added to table "author" because "random" is not an input argument + of the function "full_name"' + code: constraint-violation + +- description: Try adding a computed field with a non-JSON session argument + url: /v1/query + status: 400 + query: + type: add_computed_field + args: + table: author + name: fetch_articles + definition: + function: fetch_articles + table_argument: author_row + session_argument: search + response: + internal: + - definition: + definition: + function: + schema: public + name: fetch_articles + table_argument: author_row + session_argument: search + name: fetch_articles + comment: + table: + schema: public + name: author + reason: 'in table "author": in computed field "fetch_articles": the computed field + "fetch_articles" cannot be added to table "author" because "search" argument + of the function "fetch_articles" is not of type JSON' + type: computed_field + path: $.args + error: 'in table "author": in computed field "fetch_articles": the computed field + "fetch_articles" cannot be added to table "author" because "search" argument of + the function "fetch_articles" is not of type JSON' + code: constraint-violation diff --git a/server/tests-py/queries/v1/computed_fields/setup.yaml b/server/tests-py/queries/v1/computed_fields/setup.yaml index 1dd0ae7ef99..10129e421c7 100644 --- a/server/tests-py/queries/v1/computed_fields/setup.yaml +++ b/server/tests-py/queries/v1/computed_fields/setup.yaml @@ -67,6 +67,11 @@ args: SELECT 'Hello, World!'::text $$ LANGUAGE sql STABLE; + CREATE FUNCTION test_session(author_row author, key text, session json) + RETURNS TEXT AS $$ + SELECT $3->>$2 + $$ LANGUAGE sql STABLE; + - type: track_table args: name: author diff --git a/server/tests-py/queries/v1/computed_fields/teardown.yaml b/server/tests-py/queries/v1/computed_fields/teardown.yaml index bab2b448b27..e18fd0574e5 100644 --- a/server/tests-py/queries/v1/computed_fields/teardown.yaml +++ b/server/tests-py/queries/v1/computed_fields/teardown.yaml @@ -7,6 +7,7 @@ args: DROP FUNCTION fetch_articles(text, author); DROP FUNCTION fetch_articles_volatile(text, author); DROP FUNCTION full_name(author); + DROP FUNCTION test_session(author, text, json); DROP TABLE article; DROP TABLE author; cascade: true diff --git a/server/tests-py/queries/v1/metadata/export_metadata.yaml b/server/tests-py/queries/v1/metadata/export_metadata.yaml index 29a2d386385..b9f8736e168 100644 --- a/server/tests-py/queries/v1/metadata/export_metadata.yaml +++ b/server/tests-py/queries/v1/metadata/export_metadata.yaml @@ -30,6 +30,12 @@ response: schema: public name: fetch_articles table_argument: author_row + - name: test_session + definition: + function: + schema: public + name: test_session + session_argument: session functions: - function: schema: public diff --git a/server/tests-py/queries/v1/metadata/setup.yaml b/server/tests-py/queries/v1/metadata/setup.yaml index 936cfecbaad..715a63ce65b 100644 --- a/server/tests-py/queries/v1/metadata/setup.yaml +++ b/server/tests-py/queries/v1/metadata/setup.yaml @@ -122,6 +122,23 @@ args: function: fetch_articles table_argument: author_row +#Computed field with session argument +- type: run_sql + args: + sql: | + CREATE FUNCTION test_session(author_row author, key text, session json) + RETURNS TEXT AS $$ + SELECT $3->>$2 + $$ LANGUAGE sql STABLE; + +- type: add_computed_field + args: + table: author + name: test_session + definition: + function: test_session + session_argument: session + - type: run_sql args: sql: | diff --git a/server/tests-py/queries/v1/metadata/teardown.yaml b/server/tests-py/queries/v1/metadata/teardown.yaml index 70b6243f41b..219a654a547 100644 --- a/server/tests-py/queries/v1/metadata/teardown.yaml +++ b/server/tests-py/queries/v1/metadata/teardown.yaml @@ -6,5 +6,5 @@ args: cascade: true sql: | drop table article cascade; - drop table author; + drop table author cascade; drop table text_result cascade; From 3ba344befb1d498d473beea668de0053d03b3c25 Mon Sep 17 00:00:00 2001 From: Marion Schleifer Date: Mon, 27 Apr 2020 21:02:15 +0200 Subject: [PATCH 2/2] docs: data validations (close #4085) (#4260) --- CHANGELOG.md | 2 + .../graphql/manual/schema/computed-fields.rst | 4 +- .../manual/schema/custom-functions.rst | 16 +- .../manual/schema/data-validations.rst | 359 ++++++++++++++++++ docs/graphql/manual/schema/index.rst | 7 +- .../manual/schema/relationships/index.rst | 8 +- docs/graphql/manual/schema/views.rst | 4 +- .../manual/schema/actions-data-validation.png | Bin 0 -> 51621 bytes .../manual/schema/validation-actions-def.png | Bin 0 -> 10814 bytes .../validation-add-check-constraint.png | Bin 0 -> 15733 bytes .../schema/validation-author-isactive.png | Bin 0 -> 23002 bytes .../manual/schema/validation-not-empty.png | Bin 0 -> 9405 bytes 12 files changed, 385 insertions(+), 15 deletions(-) create mode 100644 docs/graphql/manual/schema/data-validations.rst create mode 100755 docs/img/graphql/manual/schema/actions-data-validation.png create mode 100644 docs/img/graphql/manual/schema/validation-actions-def.png create mode 100644 docs/img/graphql/manual/schema/validation-add-check-constraint.png create mode 100644 docs/img/graphql/manual/schema/validation-author-isactive.png create mode 100644 docs/img/graphql/manual/schema/validation-not-empty.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d0158c914d..0ea579cdc62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -278,6 +278,7 @@ A new CLI migrations image is introduced to account for the new migrations workf (close #3969) (#4145) ### Bug fixes and improvements + - server: improve performance of replace_metadata tracking many tables (fix #3802) - server: option to reload remote schemas in 'reload_metadata' API (fix #3792, #4117) - server: fix various space leaks to avoid excessive memory consumption @@ -361,3 +362,4 @@ Read more about it in the [docs](https://hasura.io/docs/1.0/graphql/manual/auth/ - server: check expression in update permissions (close #384) (rfc #3750) (#3804) - console: show pre-release update notifications with opt out option (#3888) - console: handle invalid keys in permission builder (close #3848) (#3863) +- docs: add page on data validation to docs (close #4085) (#4260) diff --git a/docs/graphql/manual/schema/computed-fields.rst b/docs/graphql/manual/schema/computed-fields.rst index 59ecbcafc3c..f24fdc03782 100644 --- a/docs/graphql/manual/schema/computed-fields.rst +++ b/docs/graphql/manual/schema/computed-fields.rst @@ -16,8 +16,8 @@ What are computed fields? ------------------------- Computed fields are virtual values or objects that are dynamically computed and can be queried along with a table's -columns. Computed fields are computed when requested for via SQL functions using other columns of the table and other -custom inputs if needed. +columns. Computed fields are computed when requested for via `custom SQL functions `__ +using other columns of the table and other custom inputs if needed. .. note:: diff --git a/docs/graphql/manual/schema/custom-functions.rst b/docs/graphql/manual/schema/custom-functions.rst index 9c4828a33a5..38cb3e07226 100644 --- a/docs/graphql/manual/schema/custom-functions.rst +++ b/docs/graphql/manual/schema/custom-functions.rst @@ -4,8 +4,8 @@ .. _custom_sql_functions: -Customise schema with SQL functions -=================================== +Extend schema with SQL functions +================================ .. contents:: Table of contents :backlinks: none @@ -18,15 +18,19 @@ What are custom SQL functions? Custom SQL functions are `user-defined SQL functions `_ that can be used to either encapsulate some custom business logic or extend the built-in SQL functions and operators. -Hasura GraphQL engine lets you expose certain types of custom functions over the GraphQL API to allow querying them -using both ``queries`` and ``subscriptions``. +Hasura GraphQL engine lets you expose certain types of custom functions as top level fields in the GraphQL API to allow +querying them using both ``queries`` and ``subscriptions``. + +.. note:: + + Custom SQL functions can also be queried as :ref:`computed fields ` of tables. .. _supported_sql_functions: Supported SQL functions ------------------------ +*********************** -Currently, only functions which satisfy the following constraints can be exposed over the GraphQL API +Currently, only functions which satisfy the following constraints can be exposed as top level fields in the GraphQL API (*terminology from* `Postgres docs `__): - **Function behaviour**: ONLY ``STABLE`` or ``IMMUTABLE`` diff --git a/docs/graphql/manual/schema/data-validations.rst b/docs/graphql/manual/schema/data-validations.rst new file mode 100644 index 00000000000..f28ea7e40f6 --- /dev/null +++ b/docs/graphql/manual/schema/data-validations.rst @@ -0,0 +1,359 @@ +.. meta:: + :description: Data validations in Hasura + :keywords: hasura, docs, schema, data validation + +.. _data_validations: + +Data validations +================ + +.. contents:: Table of contents + :backlinks: none + :depth: 2 + :local: + +Overview +-------- + +Many times, we need to perform validations of input data before inserting or +updating objects. + +The best solution to implement a validation depends on the complexity of the +validation logic and the layer where you would like to add it. + +- If you would like the validation logic to be a part of your database schema, + Postgres check constraints or triggers would be ideal solutions to add your + validation. + +- If you would like the validation logic to be at the GraphQL API layer, Hasura + permissions can be used to add your validation. + +- If the validation logic requires complex business logic and/or needs + information from external sources, you can use Hasura Actions to perform your + validation. + +These solutions are explained in some more detail below. + +Using Postgres check constraints +-------------------------------- + +If the validation logic can be expressed by using only static values and the +columns of the table, you can use `Postgres check constraints `__. + +**Example:** Check that the ``rating`` for an author is between 1 and 10 only. + +Let's say we have a table: + +.. code-block:: sql + + author (id uuid, name text, rating integer) + +Now, we can head to the ``Modify`` tab in the table page and add a check +constraint in the ``Check Constraints`` section: + +.. thumbnail:: ../../../img/graphql/manual/schema/validation-add-check-constraint.png + :alt: Add check constraint + +If someone now tries to add an author with a rating of ``11``, the following +error is thrown: + + +.. graphiql:: + :view_only: + :query: + mutation { + insert_author( + objects: { + name: "Enid Blyton", + rating: 11 + }) { + affected_rows + } + } + :response: + { + "errors": [ + { + "message": "Check constraint violation. new row for relation \"author\" violates check constraint \"authors_rating_check\"", + "extensions": { + "path": "$.selectionSet.insert_author.args.objects", + "code": "permission-error" + } + } + ] + } + +Learn more about `Postgres check constraints `__. + +Using Postgres triggers +----------------------- + +If the validation logic is more complex and requires the use of data from other tables +and/or functions, then you can use `Postgres triggers `__. + +**Example:** Validate that an article's ``content`` does not exceed a certain number of words. + +Suppose we have the following table: + +.. code-block:: sql + + article (id uuid, title text, content text) + +Now, we can head to the ``Data -> SQL`` tab in the console and +create a `Postgres function `__ +that checks if an article's content exceeds a certain number of words, +and then add a `Postgres trigger `__ +that will call this function every time before an article is inserted or updated. + +.. code-block:: plpgsql + + CREATE FUNCTION check_content_length() + RETURNS trigger AS $$ + DECLARE content_length INTEGER; + BEGIN + -- split article content into words and get count + select array_length(regexp_split_to_array(NEW.content, '\s'),1) INTO content_length; + + -- throw an error if article content is too long + IF content_length > 100 THEN + RAISE EXCEPTION 'Content can not have more than 100 words'; + END IF; + + -- return the article row if no error + RETURN NEW; + END; + $$ LANGUAGE plpgsql; + + CREATE TRIGGER check_content_length_trigger + BEFORE INSERT OR UPDATE ON "article" + FOR EACH ROW + EXECUTE PROCEDURE check_content_length(); + + +Now, if we try to insert an article whose content has more than 100 words, we'll receive +the following error: + +.. graphiql:: + :view_only: + :query: + mutation { + insert_article( + objects: { + title: "lorem ipsum" + content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean et nisl dolor. Nulla eleifend odio et velit aliquet, sed convallis quam bibendum. Cras consequat elit quis est vehicula, nec dignissim dolor cursus. Phasellus suscipit magna ac turpis pulvinar ultricies. Nulla sed lacus sed metus egestas scelerisque nec sed urna. Fusce lorem velit, efficitur sed luctus in, fringilla ac urna. Maecenas fermentum augue sit amet malesuada imperdiet. Suspendisse mattis dignissim quam, at tempor dui tincidunt sed. Maecenas placerat erat nec erat aliquet rutrum. Mauris congue velit nec ultrices dapibus. Duis aliquam, est ac ultricies viverra, ante augue dignissim massa, quis iaculis ex dui in ex. Curabitur pharetra neque ac nisl fringilla, vel pellentesque orci molestie.", + } + ) { + affected_rows + } + } + :response: + { + "errors": [ + { + "message": "postgres query error", + "extensions": { + "internal": { + "error": { + "exec_status": "FatalError", + "message": "Content can not have more than 100 words", + "status_code": "P0001", + }, + }, + "path": "$.selectionSet.insert_article.args.objects", + "code": "unexpected" + } + } + ] + } + +Learn more about `Postgres triggers `__. + +Using Hasura permissions +------------------------ + +If the validation logic can be expressed **declaratively** using static values and +data from the database, then you can use :ref:`row level permissions ` +to perform the validations. (Read more about :ref:`Authorization `). + +**Example 1:** Validate that an ``article`` can be inserted only if ``title`` is not empty. + +Suppose, we have a table: + +.. code-block:: sql + + article (id uuid, title text, content text, author_id uuid) + +Now, we can create a role ``user`` and add the following rule: + +.. thumbnail:: ../../../img/graphql/manual/schema/validation-not-empty.png + :alt: validation using permission: title cannot be empty + +If we try to insert an article with ``title = ""``, we will get a ``permission-error``: + +.. graphiql:: + :view_only: + :query: + mutation { + insert_article( + objects: { + title: "" + content: "Lorem ipsum dolor sit amet", + } + ) { + affected_rows + } + } + :response: + { + "errors": [ + { + "message": "Check constraint violation. insert check constraint failed", + "extensions": { + "path": "$.selectionSet.insert_article.args.objects", + "code": "permission-error" + } + } + ] + } + +**Example 2:** Validate that an ``article`` can be inserted only if its ``author`` is active. + +Suppose, we have 2 tables: + +.. code-block:: sql + + author (id uuid, name text, is_active boolean) + article (id uuid, author_id uuid, content text) + +Also, suppose there is an :ref:`object relationship ` ``article.author`` defined as: + +.. code-block:: sql + + article.author_id -> author.id + +Now, we can create a role ``user`` and add the following rule: + +.. thumbnail:: ../../../img/graphql/manual/schema/validation-author-isactive.png + :alt: validation using permissions: author should be active + +If we try to insert an article for an author for whom ``is_active = false``, we +will receive a ``permission-error`` : + +.. graphiql:: + :view_only: + :query: + mutation { + insert_article( + objects: { + title: "lorem ipsum" + content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + author_id: 2 + } + ) { + affected_rows + } + } + :response: + { + "errors": [ + { + "message": "Check constraint violation. insert check constraint failed", + "extensions": { + "path": "$.selectionSet.insert_article.args.objects", + "code": "permission-error" + } + } + ] + } + + +.. note:: + + Permissions are scoped to a user's role. So, if a validation check + needs to be global then you will have to define it for all roles which have + insert/update permissions. + + A few features on the roadmap should simplify this experience in the future. + +Using Hasura Actions +-------------------- + +If the validation requires complex custom business logic and/or needs information +from external sources, you can use :ref:`Actions ` to perform your +validation. + +**Example:** Check with an external service that an author's name is not black-listed +before inserting them. + +Let's assume we have an external service that stores and manages black-listed authors. +Before inserting an author we need to check with this service if they are black-listed +or not. + +The validation process looks as follows: + +.. thumbnail:: ../../../img/graphql/manual/schema/actions-data-validation.png + :alt: validation using actions: article not blacklisted + :width: 60% + + +Actions allow us to define :ref:`custom types ` in our GraphQL schema. + +We create a new action called ``InsertAuthor`` that takes an ``author`` object with type ``AuthorInput`` as input and +returns an object of type ``AuthorOutput``: + +.. thumbnail:: ../../../img/graphql/manual/schema/validation-actions-def.png + :alt: Create action + +The business logic of an action - in our case the author validation - happens in the :ref:`action handler ` +which is an HTTP webhook which contains the code to call the external service. + +The following is a sample code that could be added to the event handler to implement the data validation: + +.. code-block:: javascript + + function getBlacklistedAuthorsFromApi() { + // make external api call & return black-listed authors list + } + + function insertAuthorViaHasura() { + // run insert_author mutation & return response + } + + const blacklistedAuthors = getBlacklistedAuthorsFromApi(); + + if (blacklistedAuthors.includes(author.name)) { + return res.status(400).json({ message: "Author is blacklisted" }); + } else { + const insertAuthorResponse = insertAuthorViaHasura(); + + return res.json(insertAuthorResponse); + } + +When we now insert an author, our action handler will be called and it will check if the author is black-listed. +If it's not, the author will be inserted and the ``id`` will be returned. If the author is black-listed, +we get the following error message: + +.. graphiql:: + :view_only: + :query: + mutation insertArticle { + InsertAuthor(author: { name: "Thanos" }) { + id + } + } + :response: + { + "errors": [ + { + "extensions": { + "path": "$", + "code": "unexpected" + }, + "message": "Author is blacklisted" + } + ] + } + +.. note:: + + For actual examples of data validations with actions, refer to the `actions examples repo `__. diff --git a/docs/graphql/manual/schema/index.rst b/docs/graphql/manual/schema/index.rst index b1724a20c8f..a26420ea1db 100644 --- a/docs/graphql/manual/schema/index.rst +++ b/docs/graphql/manual/schema/index.rst @@ -30,11 +30,12 @@ Postgres constructs. Basics Relationships - Customise with views - Customise with SQL functions + Extend with views + Extend with SQL functions Default field values - Enum type fields + enums computed-fields custom-field-names + data-validations Using an existing database Export GraphQL schema diff --git a/docs/graphql/manual/schema/relationships/index.rst b/docs/graphql/manual/schema/relationships/index.rst index b4e60d1d60b..f0163872270 100644 --- a/docs/graphql/manual/schema/relationships/index.rst +++ b/docs/graphql/manual/schema/relationships/index.rst @@ -17,6 +17,8 @@ be connected via relationships. Let's say we have the following tables in our database: ``author``, ``passport_info``, ``article`` and ``tag``. +.. _table_relationships: + Table relationships ------------------- @@ -36,11 +38,13 @@ following types of table relationships: | | | - a ``tag`` can have many ``articles`` | +------------------+-----------------------------------+------------------------------------------------+ +.. _graphql_relationships: + GraphQL schema relationships ---------------------------- -As you can see, each table relationship will have two component relationships (one in either direction) in the GraphQL -schema. These relationships can be one of the following types: +Each table relationship, as you can see from the above section, will have two component relationships +(one in either direction) in the GraphQL schema. These relationships can be one of the following types: +-----------------------------------------+------------------------------------------+---------------------------------------------------------------------------------------+ | Type | Example | Meaning | diff --git a/docs/graphql/manual/schema/views.rst b/docs/graphql/manual/schema/views.rst index e7f317fa8db..a6b25166447 100644 --- a/docs/graphql/manual/schema/views.rst +++ b/docs/graphql/manual/schema/views.rst @@ -4,8 +4,8 @@ .. _custom_views: -Customise schema with views -=========================== +Extend schema with views +======================== .. contents:: Table of contents :backlinks: none diff --git a/docs/img/graphql/manual/schema/actions-data-validation.png b/docs/img/graphql/manual/schema/actions-data-validation.png new file mode 100755 index 0000000000000000000000000000000000000000..f5c62a11978e1dbdc876bac7459b775833e8b603 GIT binary patch literal 51621 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 NLPS=$Oi=Ih{{c3UD^vgg literal 0 HcmV?d00001 diff --git a/docs/img/graphql/manual/schema/validation-actions-def.png b/docs/img/graphql/manual/schema/validation-actions-def.png new file mode 100644 index 0000000000000000000000000000000000000000..dc4d6889c9977c2b74c96f679f20af100dfdd562 GIT binary patch literal 10814 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 E5AsPZS^xk5 literal 0 HcmV?d00001 diff --git a/docs/img/graphql/manual/schema/validation-add-check-constraint.png b/docs/img/graphql/manual/schema/validation-add-check-constraint.png new file mode 100644 index 0000000000000000000000000000000000000000..7fb926db023d6b8084119a2cc5d49751366d059d GIT binary patch literal 15733 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 literal 0 HcmV?d00001 diff --git a/docs/img/graphql/manual/schema/validation-not-empty.png b/docs/img/graphql/manual/schema/validation-not-empty.png new file mode 100644 index 0000000000000000000000000000000000000000..4db62a6a6f5e978f4c4897822ab6dc6932d78553 GIT binary patch literal 9405 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 Sn}5G05ooCCsMac5hW-~_LlD>i literal 0 HcmV?d00001