├── README.md ├── services ├── blog │ ├── config │ │ └── initMongo.js │ ├── model │ │ └── blog.model.js │ ├── blog.service.js │ └── functions │ │ └── blog.grpc.js └── product │ ├── config │ └── initMongo.js │ ├── model │ └── prodcut.model.js │ ├── product.service.js │ └── functions │ └── product.grpc.js ├── client ├── routes │ ├── index.routes.js │ ├── blog.routes.js │ └── product.routes.js ├── app.js └── contorller │ ├── blog.controller.js │ └── product.contoller.js ├── package.json └── protos ├── blog.proto └── product.proto /README.md: -------------------------------------------------------------------------------- 1 | # grpc-node-1 2 | -------------------------------------------------------------------------------- /services/blog/config/initMongo.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /services/product/config/initMongo.js: -------------------------------------------------------------------------------- 1 | const { default: mongoose } = require("mongoose"); 2 | module.exports = mongoose.connect("mongodb://localhost:27017/gRPC-nodejs").then(console.log("connect too mongo db")); 3 | -------------------------------------------------------------------------------- /client/routes/index.routes.js: -------------------------------------------------------------------------------- 1 | const { BlogRouter } = require("./blog.routes"); 2 | const { productRouter } = require("./product.routes"); 3 | 4 | const router = require("express").Router(); 5 | 6 | router.use("/blog", BlogRouter); 7 | router.use("/product", productRouter); 8 | module.exports = { 9 | AllRoutes: router 10 | } -------------------------------------------------------------------------------- /client/app.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const { AllRoutes } = require("./routes/index.routes"); 3 | const app = express(); 4 | 5 | app.use(express.json()); 6 | app.use(express.urlencoded({ extended: true })); 7 | app.use(AllRoutes); 8 | app.listen(4000, () => { 9 | console.log("Client running over port 4000"); 10 | }) 11 | -------------------------------------------------------------------------------- /services/blog/model/blog.model.js: -------------------------------------------------------------------------------- 1 | const { default: mongoose, model } = require("mongoose"); 2 | 3 | const blogSchema = new mongoose.Schema({ 4 | title: { type: String }, 5 | text: { type: String }, 6 | }) 7 | blogSchema.set('toJSON', { 8 | virtuals: true 9 | }); 10 | module.exports = { 11 | BlogModel: mongoose.model("blog", blogSchema) 12 | } -------------------------------------------------------------------------------- /services/product/model/prodcut.model.js: -------------------------------------------------------------------------------- 1 | const { default: mongoose, model } = require("mongoose"); 2 | 3 | const productSchema = new mongoose.Schema({ 4 | title: { type: String }, 5 | price: { type: String } 6 | }) 7 | productSchema.set('toJSON', { 8 | virtuals: true 9 | }); 10 | 11 | 12 | module.exports = { 13 | ProductModel: mongoose.model("product", productSchema) 14 | } -------------------------------------------------------------------------------- /client/routes/blog.routes.js: -------------------------------------------------------------------------------- 1 | const { ListBlog, CreateBlog, UpdateBlog, DeleteBlog, GetBlog } = require("../contorller/Blog.contoller"); 2 | 3 | const router = require("express").Router(); 4 | 5 | router.get("/create", CreateBlog); 6 | router.get("/get", GetBlog); 7 | router.get("/list", ListBlog); 8 | router.get("/update", UpdateBlog); 9 | router.get("/delete", DeleteBlog); 10 | 11 | module.exports = { 12 | BlogRouter: router 13 | } -------------------------------------------------------------------------------- /client/routes/product.routes.js: -------------------------------------------------------------------------------- 1 | const { ListProduct, CreateProduct, UpdateProduct, DeleteProduct, GetProduct } = require("../contorller/product.contoller"); 2 | 3 | const router = require("express").Router(); 4 | 5 | router.get("/create", CreateProduct); 6 | router.get("/get", GetProduct); 7 | router.get("/list", ListProduct); 8 | router.get("/update", UpdateProduct); 9 | router.get("/delete", DeleteProduct); 10 | 11 | module.exports = { 12 | productRouter: router 13 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grpc-project", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@grpc/grpc-js": "^1.9.0", 13 | "@grpc/proto-loader": "^0.7.8", 14 | "mongoose": "^7.4.3", 15 | "mongoose-sequence": "^5.3.1", 16 | "normalize-mongoose": "^1.0.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /protos/blog.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package blogPackage; 3 | 4 | message Blog { 5 | string id = 1; 6 | string title = 2; 7 | string text = 3; 8 | } 9 | message BlogId { 10 | string id = 1; 11 | } 12 | message BlogList { 13 | repeated Blog blogs = 1; 14 | } 15 | message NewBlog{ 16 | string title = 1; 17 | string text = 2; 18 | } 19 | message Empty {}; 20 | message Result { 21 | string status = 1; 22 | } 23 | service BlogService { 24 | rpc ListBlog (Empty) returns (BlogList); 25 | rpc GetBlog (BlogId) returns (Blog); 26 | rpc CreateBlog (NewBlog) returns (Result); 27 | rpc UpdateBlog (Blog) returns (Result); 28 | rpc DeleteBlog (BlogId) returns (Result); 29 | } 30 | -------------------------------------------------------------------------------- /protos/product.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package productPackage; 3 | 4 | message Product { 5 | string id = 1; 6 | string title = 2; 7 | string price = 3; 8 | } 9 | message ProductId { 10 | string id = 1; 11 | } 12 | message ProductList { 13 | repeated Product products = 1; 14 | } 15 | message NewProduct{ 16 | string title = 1; 17 | string price = 2; 18 | } 19 | message Empty {}; 20 | message Result { 21 | string status = 1; 22 | }; 23 | service ProductService { 24 | rpc ListProduct (Empty) returns (ProductList); 25 | rpc GetProduct (ProductId) returns (Product); 26 | rpc CreateProduct (NewProduct) returns (Result); 27 | rpc UpdateProduct (Product) returns (Result); 28 | rpc DeleteProduct (ProductId) returns (Result); 29 | } 30 | -------------------------------------------------------------------------------- /services/blog/blog.service.js: -------------------------------------------------------------------------------- 1 | require("./config/initMongo"); 2 | const grpc = require("@grpc/grpc-js"); 3 | const protoLoader = require("@grpc/proto-loader"); 4 | const path = require("path"); 5 | const blogProto = protoLoader.loadSync(path.join(__dirname, "..", "..", "protos/blog.proto")); 6 | const { blogPackage } = grpc.loadPackageDefinition(blogProto); 7 | const blogURL = "localhost:4002"; 8 | const { ListBlog, GetBlog, CreateBlog, UpdateBlog, DeleteBlog } = require("./functions/blog.grpc"); 9 | function initGRPC() { 10 | const server = new grpc.Server(); 11 | server.addService(blogPackage.BlogService.service, { 12 | ListBlog, 13 | GetBlog, 14 | CreateBlog, 15 | UpdateBlog, 16 | DeleteBlog 17 | }) 18 | server.bindAsync(blogURL, grpc.ServerCredentials.createInsecure(), (err, port) => { 19 | if (err) return console.log(err.message); 20 | server.start(); 21 | console.log(`blog service run over ${port}`); 22 | }) 23 | } 24 | module.exports = initGRPC; 25 | -------------------------------------------------------------------------------- /services/product/product.service.js: -------------------------------------------------------------------------------- 1 | require("./config/initMongo"); 2 | const grpc = require("@grpc/grpc-js"); 3 | const protoLoader = require("@grpc/proto-loader"); 4 | const path = require("path"); 5 | const productProto = protoLoader.loadSync(path.join(__dirname, "..", "..", "protos/product.proto")); 6 | const { productPackage } = grpc.loadPackageDefinition(productProto); 7 | const productURL = "localhost:4001"; 8 | const { ListProduct, GetProduct, CreateProduct, UpdateProduct, DeleteProduct } = require("./functions/product.grpc"); 9 | function initGRPC() { 10 | const server = new grpc.Server(); 11 | server.addService(productPackage.ProductService.service, { 12 | ListProduct, 13 | GetProduct, 14 | CreateProduct, 15 | UpdateProduct, 16 | DeleteProduct 17 | }) 18 | server.bindAsync(productURL, grpc.ServerCredentials.createInsecure(), (err, port) => { 19 | if (err) return console.log(err.message); 20 | server.start(); 21 | console.log(`product service run over ${port}`); 22 | }) 23 | } 24 | module.exports = initGRPC; 25 | -------------------------------------------------------------------------------- /client/contorller/blog.controller.js: -------------------------------------------------------------------------------- 1 | const grpc = require("@grpc/grpc-js"); 2 | const protoLoader = require("@grpc/proto-loader"); 3 | const path = require("path"); 4 | const blogProto = protoLoader.loadSync(path.join(__dirname, "..", "..", "protos/blog.proto")); 5 | const { blogPackage } = grpc.loadPackageDefinition(blogProto); 6 | const blogURL = "localhost:4002"; 7 | const BlogClient = new blogPackage.BlogService(blogURL, grpc.credentials.createInsecure()); 8 | 9 | function ListBlog(req, res, next) { 10 | BlogClient.ListBlog(null, (err, data) => { 11 | if (err) return res.json(err); 12 | return res.json(data); 13 | }) 14 | } 15 | function GetBlog(req, res, next) { 16 | const { id } = req.query; 17 | BlogClient.GetBlog({ id }, (err, data) => { 18 | if (err) return res.json(err); 19 | return res.json(data); 20 | }) 21 | } 22 | function CreateBlog(req, res, next) { 23 | const { title, text } = req.query; 24 | BlogClient.CreateBlog({ title, text }, (err, data) => { 25 | if (err) return res.json(err); 26 | return res.json(data); 27 | }) 28 | } 29 | function DeleteBlog(req, res, next) { 30 | const { id } = req.query; 31 | BlogClient.DeleteBlog({ id }, (err, data) => { 32 | if (err) return res.json(err); 33 | return res.json(data); 34 | }) 35 | } 36 | function UpdateBlog(req, res, next) { 37 | const { id, title, text } = req.query; 38 | BlogClient.UpdateBlog({ id, title, text }, (err, data) => { 39 | if (err) return res.json(err); 40 | return res.json(data); 41 | }) 42 | 43 | } 44 | module.exports = { 45 | ListBlog, 46 | GetBlog, 47 | CreateBlog, 48 | UpdateBlog, 49 | DeleteBlog 50 | } -------------------------------------------------------------------------------- /client/contorller/product.contoller.js: -------------------------------------------------------------------------------- 1 | const grpc = require("@grpc/grpc-js"); 2 | const protoLoader = require("@grpc/proto-loader"); 3 | const path = require("path"); 4 | const productProto = protoLoader.loadSync(path.join(__dirname, "..", "..", "protos/product.proto")); 5 | const { productPackage } = grpc.loadPackageDefinition(productProto); 6 | const productURL = "localhost:4001"; 7 | const ProductClient = new productPackage.ProductService(productURL, grpc.credentials.createInsecure()); 8 | 9 | function ListProduct(req, res, next) { 10 | ProductClient.ListProduct(null, (err, data) => { 11 | if (err) return res.json(err); 12 | return res.json(data); 13 | }) 14 | } 15 | function GetProduct(req, res, next) { 16 | const { id } = req.query; 17 | ProductClient.GetProduct({ id }, (err, data) => { 18 | if (err) return res.json(err); 19 | return res.json(data); 20 | }) 21 | } 22 | function CreateProduct(req, res, next) { 23 | const { title, price } = req.query; 24 | ProductClient.CreateProduct({ title, price }, (err, data) => { 25 | if (err) return res.json(err); 26 | return res.json(data); 27 | }) 28 | } 29 | function DeleteProduct(req, res, next) { 30 | const { id } = req.query; 31 | ProductClient.DeleteProduct({ id }, (err, data) => { 32 | if (err) return res.json(err); 33 | return res.json(data); 34 | }) 35 | } 36 | function UpdateProduct(req, res, next) { 37 | const { id, title, price } = req.query; 38 | ProductClient.UpdateProduct({ id, title, price }, (err, data) => { 39 | if (err) return res.json(err); 40 | return res.json(data); 41 | }) 42 | 43 | } 44 | module.exports = { 45 | ListProduct, 46 | GetProduct, 47 | CreateProduct, 48 | UpdateProduct, 49 | DeleteProduct 50 | } -------------------------------------------------------------------------------- /services/blog/functions/blog.grpc.js: -------------------------------------------------------------------------------- 1 | const { BlogModel } = require("../model/prodcut.model") 2 | async function ListBlog(call, callback) { 3 | try { 4 | const blogs = await BlogModel.find({}); 5 | if (!blogs) return res.json({ message: "No blog found" }); 6 | callback(null, { blogs }); 7 | } catch (error) { 8 | callback(error, null) 9 | } 10 | } 11 | async function GetBlog(call, callback) { 12 | try { 13 | const { id } = call.request; 14 | const blog = await BlogModel.findOne({ _id: id }); 15 | callback(null, blog); 16 | } catch (error) { 17 | callback(error, null); 18 | } 19 | } 20 | async function CreateBlog(call, callback) { 21 | try { 22 | const blogData = call.request; 23 | const createResult = await BlogModel.create(blogData); 24 | if (createResult) callback(null, { status: "not created" }); 25 | callback(null, { status: "created" }); 26 | } catch (error) { 27 | callback(error, null); 28 | } 29 | } 30 | async function DeleteBlog(call, callback) { 31 | try { 32 | const { id } = call.request; 33 | const deleteResult = await BlogModel.deleteOne({ _id: id }); 34 | if (deleteResult.deletedCount == 0) callback(null, { status: "not deleted" }); 35 | callback(null, { status: "deleted" }); 36 | } catch (error) { 37 | callback(error, null); 38 | } 39 | } 40 | async function UpdateBlog(call, callback) { 41 | try { 42 | const { id, title, price } = call.request; 43 | const updateResult = await BlogModel.updateOne({ _id: id }, { $set: { title, price } }); 44 | if (updateResult.modifiedCount == 0) callback(null, { status: "not updated" }); 45 | callback(null, { status: "updated" }); 46 | } catch (error) { 47 | callback(error, null); 48 | } 49 | } 50 | 51 | module.exports = { 52 | ListBlog, 53 | GetBlog, 54 | CreateBlog, 55 | UpdateBlog, 56 | DeleteBlog, 57 | } -------------------------------------------------------------------------------- /services/product/functions/product.grpc.js: -------------------------------------------------------------------------------- 1 | const { ProductModel } = require("../model/prodcut.model") 2 | async function ListProduct(call, callback) { 3 | try { 4 | const products = await ProductModel.find({}); 5 | if (!products) return res.json({ message: "No product found" }); 6 | callback(null, { products }); 7 | } catch (error) { 8 | callback(error, null) 9 | } 10 | } 11 | async function GetProduct(call, callback) { 12 | try { 13 | const { id } = call.request; 14 | const product = await ProductModel.findOne({ _id: id }); 15 | callback(null, product); 16 | } catch (error) { 17 | callback(error, null); 18 | } 19 | } 20 | async function CreateProduct(call, callback) { 21 | try { 22 | const productData = call.request; 23 | const createResult = await ProductModel.create(productData); 24 | if (createResult) callback(null, { status: "not created" }); 25 | callback(null, { status: "created" }); 26 | } catch (error) { 27 | callback(error, null); 28 | } 29 | } 30 | async function DeleteProduct(call, callback) { 31 | try { 32 | const { id } = call.request; 33 | const deleteResult = await ProductModel.deleteOne({ _id: id }); 34 | if (deleteResult.deletedCount == 0) callback(null, { status: "not deleted" }); 35 | callback(null, { status: "deleted" }); 36 | } catch (error) { 37 | callback(error, null); 38 | } 39 | } 40 | async function UpdateProduct(call, callback) { 41 | try { 42 | const { id, title, price } = call.request; 43 | const updateResult = await ProductModel.updateOne({ _id: id }, { $set: { title, price } }); 44 | if (updateResult.modifiedCount == 0) callback(null, { status: "not updated" }); 45 | callback(null, { status: "updated" }); 46 | } catch (error) { 47 | callback(error, null); 48 | } 49 | } 50 | 51 | module.exports = { 52 | ListProduct, 53 | GetProduct, 54 | CreateProduct, 55 | UpdateProduct, 56 | DeleteProduct, 57 | } --------------------------------------------------------------------------------