This gRPC mode allows you to stream data from a client to server which is useful for file uploads. During client-streaming RPC, the server processes the data as it arrives which is useful when dealing with large payloads.

syntax = "proto3";  
  
package todo_service;  
  
message NoParam {  
}  
  
message TodoItem {  
  int32 id = 1;  
  string text = 2;  
}  
  
message TodoItems {  
  // Repeated is an array  
  repeated TodoItem items = 1;  
}   
  
service Todo {  
  rpc createStream(stream TodoItem) returns (TodoItem);  
}  
// server  
import type { ProtoGrpcType } from '../proto/todo';  
import * as grpc from '@grpc/grpc-js';  
import * as protoLoader from '@grpc/proto-loader';  
import type { TodoHandlers } from '../proto/todo_service/Todo';  
import type { TodoItem } from '../proto/todo_service/TodoItem';  
  
const packageDefinition = protoLoader.loadSync('proto/todo.proto', {  
	longs: String,  
	enums: String,  
	defaults: true,  
	oneofs: true,  
});  
  
const proto = grpc.loadPackageDefinition(  
	packageDefinition  
) as unknown as ProtoGrpcType;  
  
// Typed service implementation  
const todos = new Map<number, TodoItem>();  
  
const todoService: TodoHandlers = {  
	createStream: (call, callback) => {  
		let counter = 0;  
		call.on('data', (item: TodoItem) => {  
			if (!item.text) {  
				return callback({  
					code: grpc.status.INVALID_ARGUMENT,  
					details: 'Missing text',  
				});  
			}  
  
			const newTodo = { id: todos.size + 1, text: item.text };  
			todos.set(newTodo.id, newTodo);  
			counter++;  
		});  
  
		call.on('end', () => console.log(`Steram ended. Added ${counter} item(s)`));  
	},  
};  
  
// Create and start gRPC server  
const server = new grpc.Server();  
server.addService(proto.todo_service.Todo.service, todoService);  
server.bindAsync(  
	'0.0.0.0:50051',  
	grpc.ServerCredentials.createInsecure(),  
	() => {  
		console.log('gRPC server running on port 50051');  
	}  
);  
  
// client  
import grpc from '@grpc/grpc-js';  
import protoLoader from '@grpc/proto-loader';  
import type { ProtoGrpcType } from './proto/todo';  
  
const packageDef = protoLoader.loadSync('./proto/todo.proto', {  
	longs: String,  
	enums: String,  
	defaults: true,  
	oneofs: true,  
});  
  
const grpcObject = grpc.loadPackageDefinition(  
	packageDef  
) as unknown as ProtoGrpcType;  
  
const todoPackage = grpcObject.todo_service;  
  
const client = new todoPackage.Todo(  
	'localhost:50051',  
	grpc.credentials.createInsecure()  
);  
  
const stream = client.createStream((error, res) => {  
	if (error) {  
		console.error(error.message);  
	}  
  
	console.log(res);  
});  
  
stream.write({  
	text: 'Task 1',  
});  
stream.write({  
	text: 'Task 2',  
});  
stream.write({  
	text: 'Task 3',  
});  
stream.write({  
	text: 'Task 4',  
});  
stream.write({  
	text: 'Task 5',  
});