GraphQL

GraphQL Resolvers & Error Handling with Security Best Practice

March 28, 2018

author:

GraphQL Resolvers & Error Handling with Security Best Practice

# GraphQL Resolvers

GraphQL provides immense flexibility but ever wondered how it does that? The resultant payload of any GraphQL query or mutation returns a set of fields as a map. In server implementation of GraphQL, this fields actually correspond to exactly one function. This function is known as a resolver function and the only thing it does is fetch the data from its corresponding field.

On the other hand, when a server receives a query or mutation request, it typically calls all the functions of the fields which are requested as query payload. It hence resolves the query and retrieves correct data for every field. When all the resolvers are returned, server packages corresponding data in the requested format and thus sends the payload back to the client. And this how it fits usecases ranging any complexity level.

GraphQL Resolver Example:

Let us create a GraphQL Type, Query and then add its Resolver function:

type Company {
    id: ID!
    name: String
}
type Query {
    Companies: [Company]
}

// Resolver
const resolvers = {
    Query: {
        Companies: () => {
            return Company;
        }
     }
}

# GraphQL Error Handling

GraphQL usually returns a map as a response. They are mainly two keys included in this response namely Data and Error. On successful execution of a query, the Data entity contains the resultant data. But if the query operation fails before execution, Error entity will also be present with a corresponding error message as data. Syntax or validation error, missing information are usually reasons for the error.

{
   "data": { … }
   "errors":{ … }
}

Thus for error handling, we check if error key is present or not in the resultant payload and perform relevant operation accordingly.

# GraphQL Security Best Practice

GraphQL is emerging as a strong and powerful API Language. With such notions, intruders often try to figure out the loopholes in the technologies from initial boosts itself. Thus it becomes extremely important to keep the application and data secured amidst the blooming tech. It is the security of a language or platform that either makes it or breaks it.

As far as security in GraphQL is concerned, GraphQL provides some basic precautions out of the box while individual API developers must integrate complex usecases as well. To make easy for new GraphQL developers, we are listing out some primary strategies that can be implemented:

# Type System

GraphQL stores the API definition as a type system. Defining this accurately eliminates the faulty request that has nothing to do with the API queries or mutations. GraphQL validates the request inputs with the defined types and hence doesn’t really require custom configurations for each endpoint like REST does.

# Query Timeout

Probably the most basic strategy would be to set a default timeout for unconventionally large queries. Since server only requires to know the maximum allowed time for any query, it may directly respond respectively without having to know what the actual query was.

For instance, an API configured with a timeout of 8 seconds, would immediately abort the execution of any query once it reaches 8 seconds elapsed time.

# Maximum Query Depth

At times, clients or intruder would stress test the API capabilities. Since GraphQL schemas enable cyclic graphs, stuffing junk in the query becomes easy:

query badQuery {
  post(id: "#1ca3") {
    category {
      post {
        category {
          post {
            category {
              post {
                # can get even more deeper!
              }
            }
          }
        }
      }
    }
  }
}

Such haphazard attempts can be restricted if the developer knows the API and has an overall idea as to how deep a query can really be. Such a strategy is called Maximum Query Depth. GraphQL server can reject the queries merely based on AST (Abstract Syntax Tree).

This will work for complex queries but remember this won’t save you from many medium query shootup.

# Throttling

While Maximum Query Depth is useful, it sure has some limitations. Throttle on the other end can restrict a client from sending multiple requests in a given time frame. Throttle can get tricky in GraphQL as throttling the number of requests doesn’t actually help.

As even a small number of queries can at times be too complex to handle. Thus throttling in GraphQL can be achieved either with server time or query complexity.

Conclusion:

Here we first covered important concepts of GraphQL like resolvers and error handling. Both play a major role in building and utilizing GraphQL APIs. And then leaned ahead to discuss GraphQL Security loopholes with solutions.

Questions or Comments:

Got more strategies or questions in GraphQL Resolvers, Error Handling and GraphQL Security Measures? Share in the comment section below.

Leave a comment

Your email address will not be published. Required fields are marked *