Skip to content
Snippets Groups Projects
Commit ccfc3090 authored by Khalid, Rizwan (UG - Computer Science)'s avatar Khalid, Rizwan (UG - Computer Science)
Browse files

Merge branch 'apollo-gateway' into 'develop'

Apollo gateway

See merge request !5
parents e4ce716c 8c96799e
No related branches found
No related tags found
2 merge requests!8CI/CD,!5Apollo gateway
Showing with 1978 additions and 0 deletions
SECRET_KEY=SECRET_KEY_HERE
\ No newline at end of file
import { AuthenticationError } from 'apollo-server-express';
import jwt from 'jsonwebtoken';
const auth = (context) => {
const authHeader = context.req.headers.authorization;
if (authHeader) {
const token = authHeader.split('Bearer ')[1];
if (token) {
try {
const user = jwt.verify(token, process.env.SECRET_KEY);
return user;
} catch (err) {
throw new AuthenticationError('Invalid token');
}
}
throw new Error("Authentication token must be of type 'Bearer [token]");
}
throw new Error('Authorization header not present');
};
export default auth;
\ No newline at end of file
import axios from 'axios';
const COMMENTS_SERVICE_URI = "http://localhost:5003";
export default class PostsService {
static async fetchAllPostComments({ postId }) {
const { data } = await axios.get(`${COMMENTS_SERVICE_URI}/comments/post/${postId}`);
return data;
}
static async getCommentById({ id }) {
const { data } = await axios.get(`${COMMENTS_SERVICE_URI}/comments/${id}`);
return data;
}
static async deleteCommentById({ id }) {
await axios.delete(`${COMMENTS_SERVICE_URI}/comments/${id}`);
}
static async createComment(comment) {
const { data } = await axios.post(`${COMMENTS_SERVICE_URI}/comments/`, comment);
return data;
}
static async deleteAllPostComments({ postId }) {
await axios.delete(`${COMMENTS_SERVICE_URI}/comments/post/${postId}`);
}
}
\ No newline at end of file
import axios from 'axios';
const POSTS_SERVICE_URI = "http://localhost:5002";
export default class PostsService {
static async fetchAllPosts() {
const { data } = await axios.get(`${POSTS_SERVICE_URI}/posts/`);
return data;
}
static async getPostById({ id }) {
const { data } = await axios.get(`${POSTS_SERVICE_URI}/posts/${id}`);
return data;
}
static async createPost(post) {
const { data } = await axios.post(`${POSTS_SERVICE_URI}/posts/`, post);
return data;
}
static async deletePost({ id }) {
await axios.delete(`${POSTS_SERVICE_URI}/posts/${id}`);
}
static async likePost({ postId, userId }) {
await axios.patch(`${POSTS_SERVICE_URI}/posts/${postId}/like/${userId}`)
}
static async addCommentId({ commentId, postId }) {
const { data } = await axios.patch(`${POSTS_SERVICE_URI}/posts/${postId}/comment/${commentId}`);
return data;
}
static async deleteCommentId({ commentId, postId }) {
const { data } = await axios.delete(`${POSTS_SERVICE_URI}/posts/${postId}/comment/${commentId}`);
return data;
}
}
\ No newline at end of file
import axios from 'axios';
const USERS_SERVICE_URI = "http://localhost:5001/user";
export default class UsersService {
static async signup({ name, email, password }) {
const { data } = await axios.post(`${USERS_SERVICE_URI}/signup`, {
name,
email,
password
});
return data;
}
static async signin({ email, password }) {
const { data } = await axios.post(`${USERS_SERVICE_URI}/signin`, {
email,
password
});
return data;
}
static async checkUserEmail({ email }) {
const { data } = await axios.get(`${USERS_SERVICE_URI}/user/check/${email}`);
return data;
}
static async getUserById({ id }) {
const { data } = await axios.get(`${USERS_SERVICE_URI}/user/${id}`);
return data;
}
}
\ No newline at end of file
import { UserInputError } from 'apollo-server-express';
import PostsService from '../adapters/PostsService.js';
import CommentsService from '../adapters/CommentsService.js';
import UsersService from '../adapters/UsersService.js';
import auth from '../../auth/auth.js';
const commentsResolvers = {
Mutation: {
createComment: async (_, { body, postId }, context) => {
const { _id } = auth(context);
const post = await PostsService.getPostById({ id: postId });
if (post) {
const comment = await CommentsService.createComment({ body, postId, creatorId: _id });
post = await PostsService.addCommentId({ commentId: comment._id, postId });
return post;
} else throw new UserInputError( `Post with id ${postId} not found`);
},
async deleteComment(_, { commentId, postId }, context) {
const post = await PostsService.getPostById({ id: postId });
if (post) {
await CommentsService.deleteCommentById({ id: commentId });
post = await PostsService.deleteCommentId({commentId, postId});
return post;
} else {
throw new UserInputError(`Post with id ${postId} not found`);
}
}
},
Comment: {
async creator(parent) {
return await UsersService.getUserById({ id: parent.creatorId });
}
}
};
export default commentsResolvers;
\ No newline at end of file
import usersResolvers from './users.js';
import postsResolvers from './posts.js';
import commentsResolvers from './comments.js';
const resolvers = {
Query: {
...postsResolvers.Query
},
Mutation: {
...usersResolvers.Mutation,
...postsResolvers.Mutation,
...commentsResolvers.Mutation
},
Subscription: {
...postsResolvers.Subscription
},
Post: {
...postsResolvers.Post
},
Comment: {
...commentsResolvers.Comment
}
};
export default resolvers;
\ No newline at end of file
import { AuthenticationError, UserInputError } from 'apollo-server-express';
import auth from '../../auth/auth.js';
import PostsService from '../adapters/PostsService.js';
import CommentsService from '../adapters/CommentsService.js';
import UsersService from '../adapters/UsersService.js'
const postResolvers = {
Query: {
async getPosts() {
try {
const posts = await PostsService.fetchAllPosts();
return posts;
} catch (err) {
throw new Error(err);
}
},
async getPost(_, { postId }) {
try {
const post = await PostsService.getPostById({ id: postId });
if (post) {
return post;
} else {
throw new Error(`Post with id ${postId} not found`);
}
} catch (err) {
throw new Error(err);
}
}
},
Mutation: {
async createPost(_, { title, description, image }, context) {
const user = auth(context);
const newPost = {
title,
description,
image,
creatorId: user._id,
};
const post = await PostsService.createPost(newPost);
context.pubsub.publish('NEW_POST', {
newPost: post
});
return post;
},
async deletePost(_, { postId }, context) {
const user = auth(context);
try {
const post = await PostsService.getPostById({ id: postId });
if (user._id === post.creatorId) {
await PostsService.deletePost({ id: postId });
await CommentsService.deleteAllPostComments({ postId });
return 'Post deleted successfully';
} else {
throw new AuthenticationError('Authentication error');
}
} catch (err) {
throw new Error(err);
}
},
async likePost(_, { postId }, context) {
const { _id } = auth(context);
const post = await PostsService.getPostById({ id: postId });
if (post) {
post = await PostsService.likePost({postId, userId: _id})
return post;
} else throw new UserInputError(`Post with id ${postId} not found`);
}
},
Subscription: {
newPost: {
subscribe: (_, __, { pubsub }) => pubsub.asyncIterator('NEW_POST')
}
},
Post: {
async creator(parent) {
return await UsersService.getUserById({ id: parent.creatorId });
},
async comments(parent) {
return await CommentsService.fetchAllPostComments({ postId: parent._id })
}
}
};
export default postResolvers;
\ No newline at end of file
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import { UserInputError } from 'apollo-server-express';
import UsersService from '../adapters/UsersService.js';
function generateToken(user) {
return jwt.sign({ _id: user._id, email: user.email }, process.env.SECRET_KEY, { expiresIn: '1h' });
}
const usersResolvers = {
Mutation: {
async signin(_, { email, password }) {
const user = await UsersService.checkUserEmail({ email });
if (!user) {
throw new UserInputError('User not found');
}
const match = await bcrypt.compare(password, user.password);
if (!match) {
throw new UserInputError('Incorrect details');
}
const token = generateToken(user);
user['token'] = token
return user;
},
async signup(_,{ name, email, password }) {
const user = await UsersService.checkUserEmail({ email });
if (user) {
throw new UserInputError('Email already exists');
}
const hashedPassword = await bcrypt.hash(password, 12);
const newUser = await UsersService.signup({ name, email, password: hashedPassword })
const token = generateToken(newUser);
newUser['token'] = token
return newUser;
}
}
};
export default usersResolvers;
\ No newline at end of file
import { gql } from 'apollo-server-express';
const typeDefs = gql`
type User {
_id: ID!
email: String!
token: String!
name: String!
}
type Post {
_id: ID!
title: String!
description: String!
creator: User!
image: String!
likes: [String]!
comments: [Comment]!
createdAt: String!
}
type Comment {
_id: ID!
body: String!
creator: User!
postId: String!
createdAt: String!
}
type Query {
getPosts: [Post]
getPost(postId: ID!): Post
}
type Mutation {
signup(name: String!, email: String!, password: String!): User!
signin(email: String!, password: String!): User!
createPost(title: String!, description: String!, image: String!): Post!
deletePost(postId: ID!): String!
createComment(body: String!, postId: ID!): Post!
deleteComment(commentId: ID!, postId: ID!): Post!
likePost(postId: ID!): Post!
}
type Subscription {
newPost: Post!
}
`;
export default typeDefs;
\ No newline at end of file
import { ApolloServer, PubSub } from 'apollo-server-express';
import express from 'express';
import cors from 'cors';
import bodyParser from 'body-parser';
import typeDefs from './graphql/typeDefs.js';
import resolvers from './graphql/resolvers/index.js'
import dotenv from 'dotenv';
dotenv.config();
const app = express();
app.use(bodyParser.json({ limit: "30mb", extended: true }));
app.use(bodyParser.urlencoded({ limit: "30mb", extended: true }));
app.use(cors());
const pubsub = new PubSub();
const server = new ApolloServer({
typeDefs,
resolvers,
context: ({ req }) => ({ req, pubsub })
});
server.applyMiddleware({ app, path: "/graphql" });
app.listen({ port: 5000 }, () => console.log("Apollo Server running on port 5000"));
\ No newline at end of file
This diff is collapsed.
{
"name": "apollo-gateway",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"apollo-server-express": "^2.23.0",
"axios": "^0.21.1",
"bcryptjs": "^2.4.3",
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"graphql": "^15.5.0",
"jsonwebtoken": "^8.5.1"
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment