DEV Community

Aleson França
Aleson França

Posted on

🚀 Mastering GraphQL: Rest vs GraphQL, Federation and Auth.

Over the past few years, GraphQL has gained popularity as a modern alternative to REST for building API's. In this post, we'll explore the key differences between REST and GraphQL, what Federation is, and how authentication works in GraphQL API's


REST vs GraphQL: Key Differences

Request Efficiency

  • REST: Often requires multiples requests to different endpoints.
  • GraphQL: Single query can fetch everything needed in one request, reducing latency and network load.

Versioning

  • REST: Typically uses versioning in the URL (ex: /api/v1/users).
  • GraphQL: No need for versioning since clients request only the fields they need, and new fields can be added without breaking anything.

Data Structure and Flexibility

  • REST: Each endpoint returns a fixed set of data, so you often need multiple calls to get all the info you need.
  • GraphQL: The client asks for exactly what it needs, avoiding unnecessary data and extra requests.

Typing and Documentation

  • REST: May or may not be typed, depending on implementation.
  • GraphQL: Uses a strongly typed schema that serves as auto-generated documentation for developers and clients.

Backend Load

  • REST: Can overload the backend with too many requests and unnecessary data.
  • GraphQL: Requires a more optimized backend to handle dynamic and complex queries. Tools like DataLoader help prevent perfomances issues

What is GraphQL Federation ?

GraphQL Federation allows splitting a schema into multiple independent services that work together as a single API.

Benefits of Federation

  • Helps maintainability, as each team can manage its own schema.
  • Improves performance by avoiding unnecessary calls to external services.
  • Makes scaling easier by distributing different parts of the schema across multiple microservices.
  • Reduces dependencies between services, making the system more modular.

Apollo Federation is one of the most popular tools for implementing this approach.

Key Components of Apollo Federation

  • Shared Resolvers: Allow entities to be referenced across multiple subgraphs.
  • Subgraph Services: Independent services defining parts of the global schema.
  • Gateway: Combines and expose a single GraphQL endpoint.

Example of Apollo Federation

  • Defining a Subgraph (Users Service)
# users-service/schema.graphql
extend type Query {
  me: User
  user(id: ID!): User
}

type User @key(fields: "id") {
  id: ID!
  name: String!
  email: String!
}
Enter fullscreen mode Exit fullscreen mode
  • Defining Another Subgraph (Orders Service)
# orders-service/schema.graphql
extend type Query {
  orders(userId: ID!): [Order]
}

type Order {
  id: ID!
  product: String!
  price: Float!
  user: User
}

extend type User @key(fields: "id") {
  id: ID! @external
  orders: [Order]
}
Enter fullscreen mode Exit fullscreen mode
  • Setting Up the Gateway
const { ApolloGateway } = require('@apollo/gateway');
const { ApolloServer } = require('apollo-server');

const gateway = new ApolloGateway({
  serviceList: [
    { name: 'users', url: 'http://localhost:4001/graphql' },
    { name: 'orders', url: 'http://localhost:4002/graphql' }
  ]
});

const server = new ApolloServer({ gateway });
server.listen().then(({ url }) => {
  console.log(`Gateway running at ${url}`);
});
Enter fullscreen mode Exit fullscreen mode

Auth in GraphQL

Unlike REST, GraphQL has a single endpoint for all queries and mutations, so auth need a diff approach.

Example

const { ApolloServer, gql } = require('apollo-server');
const jwt = require('jsonwebtoken');

const typeDefs = gql`
  type Query {
    me: User
  }

  type User {
    id: ID!
    name: String!
    email: String!
  }
`;

const resolvers = {
  Query: {
    me: (parent, args, context) => {
      if (!context.user) {
        throw new Error("Unauthorized");
      }
      return context.user;
    },
  },
};

const getUserFromToken = (token) => {
  try {
    return jwt.verify(token, 'your_secret_key');
  } catch (error) {
    return null;
  }
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
  context: ({ req }) => {
    const token = req.headers.authorization || "";
    const user = getUserFromToken(token.replace("Bearer ", ""));
    return { user };
  },
});

server.listen().then(({ url }) => {
  console.log(`Server running at ${url}`);
});
Enter fullscreen mode Exit fullscreen mode

Common Auth methods:

  • OAuth 2.0:

    • Uses flows like auth code flow to validate users.
    • Common for third-party logins(Google, Github, etc.).
  • Auth Middleware:

    • Can validate tokens before processing queries or mutations.
    • In frameworks like Apollo Server, It's often implemented in the request context.
  • JWT (JSON Web Token):

    • Works well for both authentication and permission management.
    • The token is sent in the Authorization header.
    • Can be validated in each resolver or through middleware.

Conclusion

GraphQL brings major advantages over REST, like flexibility and efficient data fetching. Federation makes it scalable for distributed systems, and authentication can be easily implemented with JWT or OAuth.

If you’re building modern APIs, GraphQL is definitely worth considering! It integrates well with various architectures and scales as your project grows.

Enjoyed this post? Drop a comment and share your GraphQL experience!

Top comments (0)