Skip to content

Instantly share code, notes, and snippets.

@19sajib
Last active July 27, 2022 12:01
Show Gist options
  • Save 19sajib/a75f73f216fe92ee31a8fe086c7e98dc to your computer and use it in GitHub Desktop.
Save 19sajib/a75f73f216fe92ee31a8fe086c7e98dc to your computer and use it in GitHub Desktop.
18 GraphQL Interview Questions

GraphQL

Q1: What is GraphQL?

Answer: GraphQL is a query language created by Facebook in 2012 which provides a common interface between the client and the server for data fetching and manipulations.

The client asks for various data from the GraphQL server via queries. The response format is described in the query and defined by the client instead of the server: they are called client‐specified queries. The structure of the data is not hardcoded as in traditional REST APIs - this makes retrieving data from the server more efficient for the client.

Source: howtographql.com

Q2: Is GraphQL a Database Technology?

Answer: GraphQL is not database technology. GraphQL is a query language used for APIs, it is not a query language for database. GraphQL can be used with any database or even without a database.

Source: howtographql.com

Q3: What is an exclamation point in GraphQL?

Answer: That means that the field is non-nullable. By default, all types in GraphQL are nullable. When non-null is applied to the type of a field, it means that if the server resolves that field to null, the response will fail validation.

Source: stackoverflow.com

Q4: What is difference between Mutation and Query?

Answer: Technically any GraphQL query could be implemented to cause a data write. But there is a convention that any operations that cause writes should be sent explicitly via a mutation.

Besides the difference in the semantic, there is one important technical difference:

Query fields can be executed in parallel by the GraphQL engine while Mutation top-level fields MUST execute serially according to the spec.

Source: stackoverflow.com

Q5: What is GraphQL schema?

Answer: Every GraphQL server has two core parts that determine how it works: a schema and resolve functions.

The schema is a model of the data that can be fetched through the GraphQL server. It defines what queries clients are allowed to make, what types of data can be fetched from the server, and what the relationships between these types are.

Consider:

type Author {
  id: Int
  name: String
  posts: [Post]
}
type Post {
  id: Int
  title: String
  text: String
  author: Author
}
type Query {
  getAuthor(id: Int): Author
  getPostsByTitle(titleContains: String): [Post]
}
schema {
  query: Query
}

Source: dev-blog.apollodata.com

Q6: Is GraphQL only for Javascript Framework?

Answer: No. GraphQL is an API technology so it can be used in any context where an API is required.

On the backend, a GraphQL server can be implemented in any programming language that can be used to build a web server. Next to Javascript, there are popular reference implementations for Ruby, Python, Scala, Java, Clojure, Go and .NET.

Since a GraphQL API is usually operated over HTTP, any client that can speak HTTP is able to query data from a GraphQL server.

Note: GraphQL is actually transport layer agnostic, so you could choose other protocols than HTTP to implement your server.

Source: howtographql.com

Q7: Where is GraphQL useful?

Answer: GraphQL helps where your client needs a flexible response format to avoid extra queries and/or massive data transformation with the overhead of keeping them in sync.

Using a GraphQL server makes it very easy for a client side developer to change the response format without any change on the backend.

With GraphQL, you can describe the required data in a more natural way. It can speed up development, because in application structures like top-down rendering in React, the required data is more similar to your component structure.

Source: blog.risingstack.com

Q8: How to do Error Handling?

Answer: A successful GraphQL query is supposed to return a JSON object with a root field called "data". If the request fails or partially fails (e.g. because the user requesting the data doesn’t have the right access permissions), a second root field called "errors" is added to the response:

{
      "data": { ... },
      "errors": [ ... ]
}

Source: blog.risingstack.com

Q9: How to query all the GraphQL type fields without writing a long query?

Answer: Unfortunately this is not possible. GraphQL requires you to be explicit about specifying which fields you would like returned from your query.

Source: stackoverflow.com

Q10: Explain the main difference between REST and GraphQL

Answer: The core difference between GraphQL and REST APIs is that GraphQL is a specification, a query language, while REST is an architectural concept for network-based software. GraphQL uses only one endpoint but REST has multiple endpoints. GraphQL uses query, mutation and subscription but REST uses GET, PUT, POST, DELETE and PATCH. REST requires multiple requests to retrieve a complex data-set, but in GraphQL we can execute complex queries easily.

Source:

Q11: List the key concepts of the GraphQL query language

Answer: 1 – Schema Definition Language (SDL) GraphQL has its own type system. This system is used to define the schema of an API. Basically, the syntax for writing schemas is known as Schema Definition Language or SDL. Let us see how a schema looks like:

type Author {
   name: String!
   country: Int!
   books: [Book!]!
}

2 – Queries Queries are one of the fundamental reasons of using GraphQL. At its core, GraphQL is a query language. Let’s look at a simple example of query:

{
  allBooks {
    title
  }
}

3 – Mutations Mutations also follow a similar structure as queries. However, the only difference is the use of mutation keyword. We can create, update as well as delete data using mutations. Let’s take a simple example of creating a new author.

mutation {
  createAuthor(name: 'Brandon Sanderson', country: "USA") {
    name
    country
  }
}

4 – Subscriptions Another one of the important GraphQL Core Concepts is around the topic of subscriptions. In many modern application, it is important to have a real-time connection between server and client so that the client can be immediately informed about important events.

Subscriptions don’t follow the typical request-response cycle. When a client subscribes to an event, it will hold the connection. When the particular event occurs, the server pushes the data to the client.

Subscriptions are also written using the same format as queries and mutations. See below example:

subscription {
  newAuthor {
    name
    country
  }
}

Once the client sends the above subscription request to the server, a connection is opened between them. Whenever a new mutation happens that creates a new author, the server sends information to the client as below:

{
  "newAuthor": {
    "name": "Robert Jordan",
    "country": "USA"
  }
}

Source: progressivecoder.com

Q12: Does GraphQL Support Offline Usage?

Answer: GraphQL is a query language for (web) APIs, and in that sense by definition only works online. However, offline support on the client-side is a valid concern. The caching abilities of Relay and Apollo might already be enough for some use cases, but there isn’t a popular solution for actually persisting stored data yet.

Source: howtographql.com

Q13: Is it possible to use inheritance with GraphQL input types?

Answer: No, the spec does not allow input types to implement interfaces. And GraphQL type system in general does not define any form of inheritance (the extends keyword adds fields to an existing type, and isn't for inheritance). The spec is intentionally constrained to stay simple. This means that you're stuck repeating fields across input types.

That said, depending on the way you construct your schema, you could build some kind of type transformer that appends the common fields programmatically based on some meta-data, e.g. a directive.

Source: stackoverflow.com

Q14: How to do Server-side Caching?

Answer: One common concern with GraphQL, especially when comparing it to REST, are the difficulties to maintain server-side cache. With REST, it’s easy to cache the data for each endpoint, since it’s sure that the structure of the data will not change.

With GraphQL on the other hand, it’s not clear what a client will request next, so putting a caching layer right behind the API doesn’t make a lot of sense.

Server-side caching still is a challenge with GraphQL. More info about caching can be found on the GraphQL website

Source: howtographql.com

Q15: How to do Authentication and Authorization?

Answer: Authentication and authorization are often confused. Authentication describes the process of claiming an identity. That’s what you do when you log in to a service with a username and password, you authenticate yourself. Authorization on the other hand describes permission rules that specify the access rights of individual users and user groups to certain parts of the system.

Authentication in GraphQL can be implemented with common patterns such as OAuth.

To implement authorization, it is recommended to delegate any data access logic to the business logic layer and not handle it directly in the GraphQL implementation. If you want to have some inspiration on how to implement authorization, you can take a look at this blogpost on how to implement authorization using GraphQL directives.

Source: howtographql.com

Q16: Can you make a GraphQL type both an input and output type?

Answer: In the GraphQL spec, objects and input objects are distinct things. Quoting the spec for input objects:

Fields can define arguments that the client passes up with the query, to configure their behavior. These inputs can be Strings or Enums, but they sometimes need to be more complex than this.

The Object type... is inappropriate for re‐use here, because Objects can contain fields that express circular references or references to interfaces and unions, neither of which is appropriate for use as an input argument. For this reason, input objects have a separate type in the system.

An Input Object defines a set of input fields; the input fields are either scalars, enums, or other input objects. This allows arguments to accept arbitrarily complex structs.

While an implementation might provide convenience code to create an object and a corresponding input object from a single definition, under the covers, the spec indicates that they'll have to be separate things (with separate names, such as Reservation and ReservationInput).

Source: stackoverflow.com

Q17: Can you make a GraphQL type both an input and output type?

Answer: As of the time of writing, there isn't a built-in feature in GraphQL-JS or Apollo Server to handle this concern, but it's something that should definitely have a simple solution as GraphQL becomes more popular. This concern can be addressed with several approaches at several levels of the stack, and should also always be combined with rate limiting, so that people can't send too many queries to your server (this is a potential issue with REST as well).

I'll just list all of the different methods I can think of, and I'll try to keep this answer up to date as these solutions are implemented in various GraphQL servers. Some of them are quite simple, and some are more complex.

  1. Query validation: In every GraphQL server, the first step to running a query is validation - this is where the server tries to determine if there are any serious errors in the query, so that we can avoid using actual server resources if we can find that there is some syntax error or invalid argument up front. GraphQL-JS comes with a selection of default rules that follow a format pretty similar to ESLint. Just like there is a rule to detect infinite cycles in fragments, one could write a validation rule to detect queries with too much nesting and reject them at the validation stage.
  2. Query timeout: If it's not possible to detect that a query will be too resource-intensive statically (perhaps even shallow queries can be very expensive!), then we can simply add a timeout to the query execution. This has a few benefits: (1) it's a hard limit that's not too hard to reason about, and (2) this will also help with situations where one of the backends takes unreasonably long to respond. In many cases, a user of your app would prefer a missing field over waiting 10+ seconds to get a response.
  3. Query whitelisting: This is probably the most involved method, but you could compile a list of allowed queries ahead of time, and check any incoming queries against that list. If your queries are totally static (you don't do any dynamic query generation on the client with something like Relay) this is the most reliable approach. You could use an automated tool to pull query strings out of your apps when they are deployed, so that in development you write whatever queries you want but in production only the ones you want are let through. Another benefit of this approach is that you can skip query validation entirely, since you know that all possible queries are valid already. For more benefits of static queries and whitelisting, read this post: https://dev-blog.apollodata.com/5-benefits-of-static-graphql-queries-b7fa90b0b69a
  4. Query cost limiting: (Added in an edit) Similar to query timeouts, you can assign a cost to different operations during query execution, for example a database query, and limit the total cost the client is able to use per query. This can be combined with limiting the maximum parallelism of a single query, so that you can prevent the client from sending something that initiates thousands of parallel requests to your backend.

(1) and (2) in particular are probably something every GraphQL server should have by default, especially since many new developers might not be aware of these concerns. (3) will only work for certain kinds of apps, but might be a good choice when there are very strict performance or security requirements.

Source: stackoverflow.com

Q18: What is AST in GraphQL?

Answer: GraphQL is two things:

  1. A query language
  2. A Type System

When a GraphQL server receives a query to process it generally comes in as a single String. This string must be split into meaningful sub-strings (tokenization) and parsed into a representation that the machine understands. This representation is called an abstract syntax tree, or AST.

When GraphQL Processes the query, it walks the tree executing each part against the schema.

Converting raw strings to an AST is the first step of every compiler from C++ to Chrome's JavaScript's VM to Babel.

Source: stackoverflow.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment