๐Ÿ“‰๐Ÿ“ŠIntroduction to GraphQL & its concepts, limitations etc.
Branch: master
Clone or download
Fetching latest commitโ€ฆ
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
demo
resolvers
.babelrc
.gitignore
LICENSE
README.md
demo.jpg
package.json
schema.js
server.js
users.js

README.md

๐Ÿ“‰๐Ÿ“Š Introduction to GraphQL

What is GraphQL, its concepts with examples & limitations.

๐Ÿ˜ผ What is GraphQL?

  • A query language for your API.
  • GraphQL gives the power to ask for exactly what we need and nothing more.
  • Get as many as resources in a single request.
  • Evolve your API's without versions.
  • GraphQL makes it easy to build powerful tools like GraphiQL by leveraging your APIโ€™s type system.

๐Ÿ™ Concepts of GraphQL

  • Queries & Mutations - GraphQL queries are so much easier to request data than a REST API.
  • Schema & Types, Variables, Arguments - GraphQL has its own schema & type system which we are already familiar with (String, Int, [] etc.).
  • Resolver - is responsible for mapping the query to a function.
  • Validation - By using the type system, it is easy to determine whether a GraphQL query is valid or not.
  • Execution - After being validated, a GraphQL query is executed by a GraphQL server which returns a result that mirrors the shape of the requested query, typically as JSON.
  • Introspection - It's often useful to ask a GraphQL schema for information about what queries it supports.

๐Ÿฃ๐Ÿฅ Steps To Run

yarn or npm install
yarn or npm start

๐ŸŽ…๐Ÿป Demo

๐Ÿงค Libraries Used

1. Variables, Arguments & Types

Like any other programming language, GraphQL has variables, arguments. Lets see some examples.

Types

The most basic components of a GraphQL schema are object types, which just represent a kind of object you can fetch from your service, and what fields it has. If you are a web developer, you can relate this with flow or typescript.

Example:

type Person {
  name: String!
}
  • String! - name property is a non-nullable string. Meaning you will always give a value for this property.
  • More types.

Arguments

We can pass arguments to any query.

Example:

query user {
  getUser(id: 1) {
    name
    age
    gender
    picture
  }
}

Variables

So far, we have been writing all of our arguments inside the query string. But in most applications, the arguments to fields will be dynamic.

Example:

variables:

{
  "userId": 1
}

query:

query user($id: Int!) {
  getUser(id: $id) {
    name
    age
    gender
    picture,
    about
  }
}

2. ๐Ÿค” Queries (GET API's)

1. What is better than a Hello World ๐Ÿคช

query helloworld {
  hello
}

Result:

{
  "data": {
    "hello": "Hello World"
  }
}

2. To get all the users from dummy JSON.

query getAllUsers {
  getUsers {
    name
    age
    gender
    picture
  }
}

Resolver getUsers:

const getUsers = args => {
  const { gender } = args;
  if (gender) return users.filter(user => user.gender === gender);
  else return users;
};

Result:

{
  "data":{
    "users":[
      {
        "name":"Price Weber",
        "age":37,
        "gender":"male",
        "picture":"http://placehold.it/32x32"
      },
      {
        "name":"Pennington Parsons",
        "age":22,
        "gender":"male",
        "picture":"http://placehold.it/32x32"
      },
      {
        "name":"Yesenia Galloway",
        "age":36,
        "gender":"female",
        "picture":"http://placehold.it/32x32"
      }
    ]
  }
}

3. To get a single user based on an id.

query user {
  getUser(id: 1) {
    name
    age
    gender
    picture
  }
}

Resolver getUser:

export const getUser = args => {
  const { id } = args;
  const user = users.filter(user => user.id === id);
  if (user.length === 1) return user[0];
  else return `User not found for the id ${id}`;
};

Result:

{
  "data":{
    "user":{
      "name":"Price Weber",
      "age":37,
      "gender":"male",
      "picture":"http://placehold.it/32x32"
    }
  }
}

3. ๐Ÿ” Mutations

Most discussions of GraphQL focus on data fetching, but any complete data platform needs a way to modify server-side data as well. It is analogous to performing HTTP verbs such as POST, PATCH, and DELETE. Just like queries, mutation should have mutation instead of query with some id or something.

Examples: open localhost:3000/graphql to try the below.

Create a new user: (POST API ๐Ÿคช)

variables:

{
  "name": "JEDI",
  "age": 25,
  "gender": "male"
}

mutation:

mutation user($name: String!, $age: Int!, $gender: String) {
  createUser(name: $name, age: $age, gender: $gender) {
    name
    age
    gender
  }
}

Resolver for createUser:

const createUser = args => {
  const { name, age, gender } = args;
  const user = users.filter(user => user.name === name); // users from DB
  if (user.length === 0) {
    return user; // Save in DB and return
  }
  else return `A user with that name already exists.`;
};

Result:

{
  "data":{
    "createUser":{
      "name":"JEDI",
      "age":25,
      "gender":"male"
    }
  }
}

Update a existing user details: (PUT API ๐Ÿ˜)

variables:

{
  "id": 1,
  "name": "JEDI ๐Ÿ™ƒ",
  "age": 26
}

mutation:

mutation user($name: Int!, $name: String!) {
  updateUser(name: $name, age: $age, gender: $gender) {
    name
    age
  }
}

Resolver for updateUser:

const updateUser = args => {
  const { id, name, age, gender } = args;
  const user = users.filter(user => user.id === id);
  if (user.length === 1) {
    return user; // Save the updates in DB and return
  }
  else return `User doesn't exist for id ${id}.`;
};

Result:

{
  "data":{
    "updateUser":{
      "name":"JEDI ๐Ÿ™ƒ",
      "age":25
    }
  }
}

Delate a user: (DELETE API ๐Ÿ˜œ)

variables:

{
  "id": 1
}

mutation:

mutation user($id: Int!) {
  deleteUser(id: $id) {
    id
    name
    age
    gender
  }
}

Resolver deleteUser:

const deleteUser = args => {
  const { id } = args;
  const user = users.filter(user => user.id === id);
  if (user.length === 1) {
    return user; // Delete from DB and return user or return ok
  }
  else return `User doesn't exist for id ${id}.`;
};

Result:

{
  "data":{
    "deleteUser":{
      "id":1,
      "name":"Price Weber",
      "age":37,
      "gender":"male"
    }
  }
}

4. ๐ŸฅŠ Test Cases for GraphQL.

If are wondering how to write test cases for GraphQL. Here is an example for you starWarsValidation-test.js.

5. ๐Ÿท Limitations of GraphQL

  • Specific Response Structure may required - In GraphQL the response matches the shape of the query, so if you need to respond in a very specific structure, you'll have to add a transformation layer to reshape the response.

  • Handling File Upload - There is nothing about file upload in the GraphQL specification and mutations doesnโ€™t accept files in the arguments.

  • Cache at Network Level - Because of the commonly way GraphQL is used over HTTP (A POST in a single endpoint), cache at network level becomes hard. A way to solve it is to use Persisted Queries.

  • Rate Limiting - Limiting the API call's to particular query is problem in GraphQL. Github recently introducted GraphQL with different approach to solve this issue. Take a look here.

6. ๐Ÿ† References

Thanks for reading so far ๐Ÿ˜™. Please do give a star for this repo if you liked it.

MIT licensed