pro: restrict GQL operations based on node limits

Co-authored-by: Rikin Kachhia <54616969+rikinsk@users.noreply.github.com>
GitOrigin-RevId: 49268fcd36dd15e10c7b7c5fe91af93cd65cb4e2
This commit is contained in:
Naveen Naidu 2021-05-12 11:54:31 +05:30 committed by hasura-bot
parent 4c8753afca
commit 27aa5b4781
3 changed files with 51 additions and 2 deletions

View File

@ -26,6 +26,28 @@ Configuring an API limit
**Depth limits**
Restricts a GraphQL operation based on its depth, preventing deeply nested queries.
**Node limits**
Restricts a GraphQL operation based on the number of nodes. This helps in limiting the number of different pieces of related data to be fetched.
A node is defined as a field with a selection set.
For example, in the below query the number of nodes is 3 and they are ``author``, ``articles`` and ``homepage_entries``.
.. code-block:: graphql
{
author {
name
articles {
id
title
}
}
homepage_entries {
article_id
}
}
API limits are defined by **role** (anonymous, user) and can restrict request rate, depth, or both. Unique request parameters can include IP address or session variables (*x-hasura-user-id*, *x-hasura-org-id*, etc.)
Manage API limits

View File

@ -458,6 +458,9 @@ instance Arbitrary ApiLimit where
instance Arbitrary DepthLimit where
arbitrary = genericArbitrary
instance Arbitrary NodeLimit where
arbitrary = genericArbitrary
instance Arbitrary RateLimit where
arbitrary = genericArbitrary

View File

@ -17,6 +17,7 @@ data ApiLimit
= ApiLimit
{ _alRateLimit :: !(Maybe RateLimit)
, _alDepthLimit :: !(Maybe DepthLimit)
, _alNodeLimit :: !(Maybe NodeLimit)
, _alDisabled :: !Bool
} deriving (Show, Eq, Generic)
@ -25,6 +26,7 @@ instance FromJSON ApiLimit where
ApiLimit
<$> o .:? "rate_limit"
<*> o .:? "depth_limit"
<*> o .:? "node_limit"
<*> o .:? "disabled" .!= False
instance ToJSON ApiLimit where
@ -32,7 +34,7 @@ instance ToJSON ApiLimit where
genericToJSON (Casing.aesonPrefix Casing.snakeCase) { omitNothingFields = True }
emptyApiLimit :: ApiLimit
emptyApiLimit = ApiLimit Nothing Nothing False
emptyApiLimit = ApiLimit Nothing Nothing Nothing False
data RateLimit
= RateLimit
@ -109,6 +111,28 @@ newtype MaxDepth
deriving stock (Show, Eq, Ord, Generic)
deriving newtype (ToJSON, FromJSON, Arbitrary)
data NodeLimit
= NodeLimit
{ _nlGlobal :: !MaxNodes
, _nlPerRole :: !(InsOrdHashMap RoleName MaxNodes)
} deriving (Show, Eq, Generic)
instance FromJSON NodeLimit where
parseJSON = withObject "NodeLimit" $ \o ->
NodeLimit <$> o .: "global" <*> o .:? "per_role" .!= mempty
instance ToJSON NodeLimit where
toJSON =
genericToJSON (Casing.aesonPrefix Casing.snakeCase)
newtype MaxNodes
= MaxNodes { unMaxNodes :: Int }
deriving stock (Show, Eq, Ord, Generic)
deriving newtype (ToJSON, FromJSON, Arbitrary)
$(makeLenses ''ApiLimit)
$(makeLenses ''RateLimit)
$(makeLenses ''DepthLimit)
$(makeLenses ''NodeLimit)