GraphQL & NestJS
Forget the REST
Text
South Florida Code Camp
March 2, 2019
Agenda
Introduction to NestJS
GraphQL Overview
NestJS & Apollo GraphQL Server
Demo
Hello👋
I'm Siva
Architect @ Computer Enterprises Inc
#Mobile #AI #IoT #Cloud
Orlando
@ksivamuthu
nestjs
A progressive Node.js framework for building efficient, reliable and scalable server-side applications.
Extensible
Versatile
Progressive
Gives you true flexibility by allowing the use of any other libraries thanks to the modular architecture.
An adaptable ecosystem that is a fully-fledged backbone for all kinds of server-side applications.
Takes advantage of latest JavaScript features, bringing design patterns and mature solutions to node.js world.
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
Reusability
uncoupled code blocks
Middlewares
Guards
Pipes
Interceptors
Filter Exception
![](https://media0.giphy.com/media/l0JMrPWRQkTeg3jjO/giphy.gif)
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
Integration
![](https://s3.amazonaws.com/media-p.slid.es/uploads/908946/images/5147617/graphql.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/908946/images/5147628/websocket-1.png)
Websockets
![](https://s3.amazonaws.com/media-p.slid.es/uploads/908946/images/5147637/microservices.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/908946/images/5147658/logo-swagger-male.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/908946/images/5147669/mongoose-logo.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/603430/images/5237425/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/908946/images/5147651/P_JWT.jpeg)
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
![](https://media0.giphy.com/media/13RH0eYA9vEAso/giphy.gif)
NestJS Code walkthrough...
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
@Controller()
@ApiUseTags('sessions')
@UseGuards(AuthGuard)
@UseInterceptors(LoggingInterceptor)
export class SessionController {
constructor(private readonly sessionService: SessionService) {}
@Get()
public async findAll() {
return this.sessionService.findAll();
}
@Get(':id')
public async findById(@Param('id', new ParseIntPipe())id: number) {
return this.sessionService.findById(id);
}
@Post()
@UseGuards(RoleGuard)
public async create(@Body() sessionDto: SessionDTO) {
return this.sessionService.create(sessionDto);
}
}
Dependency Injection
Use guards / interceptors at this route
Use guards / interceptors at all routes
Pipes
Decorators
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
GraphQL
![](https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/GraphQL_Logo.svg/2000px-GraphQL_Logo.svg.png)
What's GraphQL?
- New API Standard by Facebook that provides a more efficient, powerful and flexible alternative to REST
- Query language for APIs.
- Declarative way of fetching and updating data.
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
Why GraphQL?
![](https://media0.giphy.com/media/b8jefh8LnBmMw/giphy.gif)
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5241298/pasted-from-clipboard.png)
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5842373/pasted-from-clipboard.png)
REST APIs
/api/v1/conferences
/api/v1/conferences/1
/api/v1/conferences/1/sessions
/api/v1/conferences/1/sessions/1/speaker
/api/v1/speakers/21
/api/v1/conference-with-sessions-and-speakers-for-mobile-app
Underfetching
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5842375/pasted-from-clipboard.png)
Required Fields in UI
{
"name" : Siva,
"imageUrl" : "https://api.adorable.io/avatars/285/1.png"
}
{
"id": 1,
"name": "Siva",
"bio": "Developer | Father of princess | Lovable husband | Focusing on goals",
"phonenumber": "9992098888",
"companyname":"Computer Enterprises Inc",
"companytitle": "Architect",
"companywebsite": "https://www.ceiamerica.com",
"blog": "https://sivamuthukumar.net",
"website": "",
"twitter":"ksivamuthu",
"imageUrl":"https://api.adorable.io/avatars/285/1.png"
}
Fields from REST Service
Overfetching
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
![](https://media2.giphy.com/media/pD9XrvhAFXHuo/giphy.gif)
How GraphQL solves these problems?
Magic !!!
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
What you want is what you get !!!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5252496/pasted-from-clipboard.png)
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5241390/pasted-from-clipboard.png)
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
Strongly typed Schema
# Object Types and Fields
type Conference {
id: Int!
name: String!
year: Int!
websiteUrl: String
location: String!
sessions: [Session]!
}
type Session {
id: Int!
title: String!
abstract: String!
level: TalkLevel
category: Category
keywords: String
speaker: Speaker!
stars: Int
}
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
Query & Mutations
// Query to read data
type Query {
conference(id: Int): Conference!
}
// Mutation to write data
type Mutation {
createSession(session: SessionInput!): Session!
}
// Input Type
input SessionInput {
title: String!
abstract: String!
...
}
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
Subscriptions
// Subscription
type Subscription {
sessionStarred: Session
}
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
Subscriptions
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
API Server
Triggers
Mutations
GQL Subscription
Web socket server
Channels
Web Socket connections
Let's play in GraphQL playground
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5252619/pasted-from-clipboard.png)
GraphQL Benefits
- GraphQL is a Specification
- Platform / Protocol / Language agnostic
- No more Over- and Under-fetching
- GraphQL versioning - Rapid Product Iterations on the Frontend
- Insightful Analytics on the Backend
- Benefits of Schema and Type system
- GraphQL Schema Stitching
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
https://graphql.org/users/
Growing users
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
![](https://media1.giphy.com/media/13hxeOYjoTWtK8/giphy.gif)
NestJS & Apollo
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5242579/pasted-from-clipboard.png)
Apollo Platform
Apollo is a family of technologies you can incrementally add to your stack.
Bind data to your UI with the ultra-flexible, community-driven GraphQL client for React, JavaScript, and native platforms.
The GraphQL gateway that provides essential features including caching, performance tracing, and error tracking
Translate your existing REST APIs and backends into GraphQL with this powerful set of tools for buliding GraphQL APIs.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5242579/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5242579/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5242579/pasted-from-clipboard.png)
Client
Engine
Server
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5260187/pasted-from-clipboard.png)
Let's see some code ...
![](https://media3.giphy.com/media/EOpZ7XsVfTN2E/giphy.gif)
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
Initialize
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
@Module({
imports: [
GraphQLModule.forRoot({
typePaths: ['./**/*.graphql'],
installSubscriptionHandlers: true,
}),
...
],
})
export class AppModule {}
Resolvers
@Resolver('Session')
export class SessionResolver {
constructor(private readonly sessionService: SessionService,
private readonly speakerService: SpeakerService) {}
@Query('sessions')
public async findAll(): Promise<Session[]> {
return this.sessionService.findAll();
}
@Query('session')
public async findById(@Args('id') id: number): Promise<Session> {
return this.sessionService.findById(id);
}
}
Mutations
@Resolver('Session')
export class SessionResolver {
constructor(private readonly sessionService: SessionService,
private readonly speakerService: SpeakerService) {}
@Mutation('starSession')
public async starSession(@Args('id') id: number) {
return await this.sessionService.incrementStars(id);
}
@Mutation('createSession')
public async createSession(@Args('session') session: SessionDTO) {
return this.sessionService.create(session);
}
}
Subscriptions
import { PubSub } from 'graphql-subscriptions';
const pubSub = new PubSub();
@Resolver('Session')
export class SessionResolver {
constructor(private readonly sessionService: SessionService,
private readonly speakerService: SpeakerService) {}
@Mutation('starSession')
public async starSession(@Args('id') id: number) {
var result = await this.sessionService.incrementStars(id);
pubSub.publish('sessionStarred', { sessionStarred: result });
return result;
}
@Subscription('sessionStarred')
public sessionStarred() {
return {
subscribe: () => pubSub.asyncIterator('sessionStarred')
};
}
}
Dataloader
Batching & Caching requests
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
Apollo Engine
Gateway that mediates between GraphQL clients and servers
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
Apollo Engine
Benefits:
- Container-based proxy.
- Performance Insights
- Per-request traces
- Error aggregation
- Caching across requests
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5259454/pasted-from-clipboard.png)
Apollo Client
Bind GraphQL data to your UI with one function call.
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
Apollo Chrome Dev Tools
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5252630/pasted-from-clipboard.png)
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
Reference
Action Items
- Learn and explore GraphQL
- Try the new framework - NestJS
- Support open-source by donating or contributing or talking.
- Be Kind & Spread Your Awesomeness ...
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
Thank you !!!
@ksivamuthu
![](https://s3.amazonaws.com/media-p.slid.es/uploads/921668/images/5258816/pasted-from-clipboard.png)
GraphQL-NestJS #TampaCC
By Sivamuthu Kumar
GraphQL-NestJS #TampaCC
NestJS & GraphQL - Repos https://github.com/ksivamuthu/demo-graphql-nestjs
- 1,574