1+ /*
2+ *
3+ * Copyright 2025 gRPC authors.
4+ *
5+ * Licensed under the Apache License, Version 2.0 (the "License");
6+ * you may not use this file except in compliance with the License.
7+ * You may obtain a copy of the License at
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ *
17+ */
18+
19+ var PROTO_PATH = __dirname + '/../protos/helloworld.proto' ;
20+
21+ var grpc = require ( '@grpc/grpc-js' ) ;
22+ var protoLoader = require ( '@grpc/proto-loader' ) ;
23+ var packageDefinition = protoLoader . loadSync (
24+ PROTO_PATH ,
25+ {
26+ keepCase : true ,
27+ longs : String ,
28+ enums : String ,
29+ defaults : true ,
30+ oneofs : true
31+ } ) ;
32+ var hello_proto = grpc . loadPackageDefinition ( packageDefinition ) . helloworld ;
33+
34+ var { Status, BadRequest} = require ( '@q42philips/node-grpc-error-details' ) ;
35+ var { Any} = require ( 'google-protobuf/google/protobuf/any_pb' ) ;
36+
37+ /**
38+ * Implements the SayHello RPC method.
39+ */
40+ function sayHello ( call , callback ) {
41+ if ( call . request . name === '' ) {
42+ // Create BadRequest detail
43+ var fieldViolation = new BadRequest . FieldViolation ( ) ;
44+ fieldViolation . setField ( 'name' ) ;
45+ fieldViolation . setDescription ( 'Name field is required' ) ;
46+
47+ var badRequest = new BadRequest ( ) ;
48+ badRequest . setFieldViolationsList ( [ fieldViolation ] ) ;
49+
50+ // Pack into Any
51+ var anyMessage = new Any ( ) ;
52+ anyMessage . pack ( badRequest . serializeBinary ( ) , 'google.rpc.BadRequest' ) ;
53+
54+ // Create Status
55+ var status = new Status ( ) ;
56+ status . setCode ( 3 ) ; // INVALID_ARGUMENT
57+ status . setMessage ( 'Request argument invalid' ) ;
58+ status . setDetailsList ( [ anyMessage ] ) ;
59+
60+ // Attach as metadata
61+ var metadata = new grpc . Metadata ( ) ;
62+ metadata . add ( 'grpc-status-details-bin' , Buffer . from ( status . serializeBinary ( ) ) ) ;
63+
64+ callback ( {
65+ code : grpc . status . INVALID_ARGUMENT ,
66+ details : 'Simple Error: The name field was empty.' ,
67+ metadata : metadata
68+ } ) ;
69+ return ;
70+ }
71+
72+ callback ( null , { message : 'Hello ' + call . request . name } ) ;
73+ }
74+
75+ /**
76+ * Starts an RPC server.
77+ */
78+ function main ( ) {
79+ var server = new grpc . Server ( ) ;
80+ server . addService ( hello_proto . Greeter . service , { sayHello : sayHello } ) ;
81+ server . bindAsync ( '0.0.0.0:50051' , grpc . ServerCredentials . createInsecure ( ) , ( ) => {
82+ console . log ( 'Server running at http://0.0.0.0:50051' ) ;
83+ } ) ;
84+ }
85+
86+ main ( ) ;
0 commit comments