Node.js로 gRPC 이용
gRPC를 알아봤으니 이를 js로 구현하는 방법을 알아보자. Typescript 기반이다. gRPC란?
Requirements
사용하는 라이브러리는 @grpc/grpc-js와 ts-proto를 사용한다. ts-proto는 아래에서 생성할 인터페이스를 Typescript에서 읽을 수 있는 타입으로 생성해 주는 역할을 해 준다.
1
2
npm install @grpc/grpc-js
npm install -D ts-proto
규약 (Contract)
서버와 클라이언트 간 통신을 위한 규약을 작성한다. 확장명은 “.proto” 파일에 저장하면 된다.
VS Code의 경우 vscode-proto3 익스텐션을 사용하면 유용하다.
코드
gRPC를 위한 언어로 작성해야 한다. 처음에는 구문과 패키지 이름을 제공해야 한다.
1
2
syntax = "proto3";
package authPackage;
패키지 이름은 원하는 대로 지정할 수 있다.
메세지 정의 (인터페이스 정의)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
enum LoginCode {
SUCCESS = 0;
FAIL = 1;
};
message LoginResult {
LoginCode loginCode = 1;
optional string token = 2;
}
message LoginRequest {
string username = 1;
string password = 2;
}
메시지의 각 필드에는 인코딩 중 사용되는 식별자인 고유 번호가 있다.
메세지 사용할 서비스 정의
위에서 정의한 인터페이스를 사용할 서비스를 정의한다.
1
2
3
service AuthService {
rpc login(LoginRequest) returns (LoginResult);
}
Typescript에서 사용할 타입 생성
ts-proto의 protoc 명령을 사용한다.
1
protoc - plugin=protoc-gen-ts_proto=.\node_modules\.bin\protoc-gen-ts_proto.cmd - ts_proto_out=. ./protos/auth.proto - ts_proto_opt=outputServices=grpc-js,env=node,esModuleInterop=true
위 명령어를 사용하면 메세지 및 서비스 코드가 포함된 auth.ts 파일이 생성된다.
서버
이제 이를 사용하기 위한 서버 정의 코드를 짠다.
1
2
3
4
5
6
7
8
import { Server, ServerCredentials } from '@grpc/grpc-js';
import { AuthServiceService } from './protos/auth';
const server = new Server();
server.addService(AuthServiceService, { login: login }); // login 은 이후에 정의할 예정입니다.
server.bindAsync('localhost:8080', ServerCredentials.createInsecure(), () => {
server.start();
});
로그인 기능 구현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { LoginCode, LoginRequest, LoginResult } from './protos/auth';
const users = [{ id: 0, username: 'admin', password: 'qwerty' }];
const login = (
call: ServerUnaryCall<LoginRequest, LoginResult>,
callback: sendUnaryData<LoginResult>
) => {
const user = users.find(
(user) =>
user.username === call.request.username &&
user.password === call.request.password
);
if (user) {
const result: LoginResult = {
loginCode: LoginCode.SUCCESS,
token: 'RandomSecretToken',
};
callback(null, result);
} else {
const result: LoginResult = {
loginCode: LoginCode.FAIL,
};
callback(null, result);
}
};
클라이언트
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { ServiceError, credentials } from '@grpc/grpc-js';
import { AuthServiceClient, LoginRequest, LoginResult } from './protos/auth';
const loginRequest: LoginRequest = {
username: 'admin',
password: 'qwerty',
};
const client = new AuthServiceClient(
'localhost:8080',
credentials.createInsecure()
);
client.login(
loginRequest,
(err: ServiceError | null, response: LoginResult) => {
console.log(JSON.stringify(response));
}
);
참고 링크
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.