Node를 위한 첫 객체 데이터베이스: Realm Node.js 를 소개합니다

Realm은 모바일 개발자들이 더 나은 앱을 보다 빠르게 개발하도록 돕기 위해, Swift, Objective-C, Java, Xamarin, React Native 등 다양한 언어와 개발환경을 지원하는 Realm Mobile Database을 구축했습니다. 오늘, 저희는 기존 제품과는 완전히 다른 제품인 Realm Node.js를 공개합니다. Realm Node.js는 Node를 위한 최초의 실제 오브젝트 데이터베이스이며, NPM을 통해 무료인 전체 공개 오픈 소스 리파지토리에서 받을 수 있습니다. 콘솔에서 npm install --save realm를 적용하면 됩니다.

수년간 많은 모바일 개발자들이 서버에서 동작하는 Realm 버전 개발을 요청해 왔기 때문에, 이 항목은 우선 순위가 높지는 않지만 백로그에 오랫동안 머물러 있었습니다. 그러나 9월에 저희의 새 제품, Realm Mobile Platform를 출시하면서 우선 순위가 바뀌었고, 잠재 고객들이 플랫폼에 대한 Node 인터페이스에 대해 질문하기 시작했으므로, 빠르게 플랫폼 제품 전략의 Node 부분을 수립한 결과 Realm Node.js가 만들어졌습니다.

Realm Node.js은 무엇이며 무슨 일을 하나요?

Realm은 객체 데이터베이스입니다. 즉, 평소처럼 객체에 대한 작업을 하면 Realm에서 이런 객체들을 디스크에 효율적으로 쉽게 저장합니다. 객체를 JSON으로 직렬화할 필요도 없고, 테이블에 저장하기 위해 ORM을 통해 보낼 필요도 없습니다. 객체 지향 개발 원칙이 지향하는 원칙을 고수하면서 만들고자 한 것을 만들면 됩니다. 모든 모바일 클라이언트단 플랫폼에서 작동하며, 이제 서버단인 Node.js에서도 작동합니다.

모바일 개발자가 Realm Node.js를 사용하면 미리 만들어진 Realm을 클라이언트에 보낼 수 있기 때문에 여러 모로 편리합니다. 앱 용량 제한과 같이 귀찮은 제약 조건을 우회할 수 있으므로 모바일 개발자들이 몇 년간 지속적으로 이런 기능 구현을 요청해왔습니다.

그러나 백엔드 개발자에게 몇몇 초기 버전을 보여주면서, Realm Node.js가 처음 상상했던 것보다 훨씬 더 Node 활용에 유용하다는 것을 알게 됐습니다. 예를 들어 여러 Node 인스턴스 간에 실시간 데이터를 편리하게 공유할 수 있습니다. 이를 설명하기 위해 Realm을 사용해서 한 기기 상의 두 개의 Node 프로세스가 객체의 직렬화와 역직렬화에 대한 부담 없이 하나의 객체를 함께 작업할 수 있도록 하는 간단한 데모를 작성했습니다.

Realm의 고유 기능인 반응형 아키텍쳐도 설명드리겠습니다. Realm은 스레드나 프로세스간 데이터베이스 동시 실행 접근 기능 제공을 위해 Multiversion Concurrency Control를 사용합니다. 즉, 쓰기 실행자에 의해 읽기 실행자가 차단되지 않으며 양측 모두 데이터베이스에 대한 일관적인 뷰를 유지하므로 Realm의 ACID가 유지됩니다. 이같은 조정을 위해 Realm은 쓰기 트랜잭션이 완료될 때 알림 시스템을 사용하여 접근자를 업데이트합니다. 이 점을 활용해서 개발자는 Realm의 알림 API으로 변경 사항에 대응할 수 있습니다. 아래 예제는 Node.js 개발자가 프로세스간 통신을 위해 Realm을 사용해서 두 독립적인 서비스를 조정하는 방법을 보여줍니다.

예제에서 Node.js 인기 라이브러리인 Express가 HTTP endpoint 생성을 위해, 웹 프레임워크 및 로깅 라이브러리인 Winston이 요청에 대한 정보 로그 생성을 위해 쓰였습니다.

var express = require('express'),
    util = require('util'),
    winston = require('winston');
    RealmWinston = require('./winston-realm').Realm;

var app = express();

// Use custom Winston transport: RealmWinston
// Writes log data to winston.realm
winston.add(RealmWinston, {});

app.get('/', function (req, res) {
  res.send('Hello World!');
  winston.info('Handled Hello World');
});

app.use(function (req, res, next) {
  res.status(404).send('Sorry can not find that!');
  winston.error('404 Error at: ' + req.url);
})

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

Realm의 장점을 활용하기 위해, Realm 파일에 Winston 로그 데이터를 저장하는 custom transport를 생성합니다. 기본 경로에 “Hello World” 응답을 확인하는 정보 메시지를 기록합니다. 다른 경로의 경우 404 error로 응답하고 오류 메시지의 해당 경로를 기록합니다. Realm에 로그 데이터를 저장한 이후에는 다른 Node 프로세스를 실행하고 변경에 대응하는 Realm 리스너를 등록할 수 있습니다.

'use strict';

var Realm = require('realm');

let winstonRealm = new Realm({
  path: 'winston.realm'
});

// Register listener to print out log messages at error level
winstonRealm.objects('Log').filtered('level = "error"').addListener((logs, changes) => {
  changes.insertions.forEach((index) => {
    let log = logs[index];
    console.log(log.message);
  })
});

리스너는 Realm이 제공하는 컬렉션 통지를 사용합니다. 컬렉션 통지는 특정 변경 사항이 발생하면 변화가 발생한, 즉 삽입, 삭제, 수정된 객체의 인덱스로 전달합니다. 아래 예제는 오류 수준의 모든 로그 쿼리에 리스너를 추가한 다음 로그 메시지를 콘솔에 표시합니다.

이 예제는 단순하지만, 이 설정은 마이크로 서비스 아키텍쳐 전반의 데이터를 조정하는 보다 복잡한 시나리오에도 사용할 수 있습니다. 전체 데모를 확인하세요. Realm의 모든 JavaScript 플랫폼은 기반 코드 구현을 공유하므로, 여러분의 Node.js 프로젝트에 Realm을 적용할 준비가 되었다면 React Native 문서와 API docs에서 유용한 정보를 찾을 수 있을 겁니다.

또 어디에 Realm Node.js를 활용할 수 있을까요? 로컬 메모리보다 큰 데이터셋을 작업할 때 사용할 수 있습니다. 질의와 관찰이 가능한 데이터 구조로도 활용할 수 있습니다. 여러 Node 인스턴스 사이에 리액티브 구조를 구축하는데도 활용해 보세요. Docker 이미지 간의 통신을 위해서도 사용할 수 있겠죠. 여러분이 적용해본 다양한 분야를 공유해 주세요!

Realm Mobile Platform으로 실시간 협업 기능과 확장이 가능한 리액티브 앱을 만들어 보세요.

Realm 모바일 플랫폼 1.0을 런칭하며, 소규모에서 대규모까지 다양한 용도에서의 제품 사용을 지원할 수 있다는 소식을 여러분께 전해드릴 수 있어 정말 기쁩니다. 우리는 지난 몇 달 동안 심혈을 기울여 버그를 수정하고 제품 완성도를 높이며 코드를 강화하였고, 뒤이어 소개드릴 여러 가지 새 기능을 추가했습니다. 리액티브 앱을 쉽고 간편하게 만들 수 있도록 돕는 Realm 모바일 플랫폼에 대해 더 알아보세요!


Realm Team

Realm Team

Realm의 미션은 더 나은 앱을 빠르게 개발할 수 있도록 돕는 것입니다. 이를 위해 저희는 개발자들이 실시간 협업, 가상 현실, 라이브 데이터 동기화, 오프라인 경험, 메시징 등 정교하고 강력한 기능을 쉽게 개발할 수 있도록 하는 개발 도구와 플랫폼을 제공하고 있습니다.

저희는 모바일 인터넷이 수많은 사용자와 보다 많은 디바이스가 속한 개방형 네트워크와 이들 간의 실시간 상호 작용으로 진화할 것이라고 믿으며, 개발자가 이같은 방향으로 발전할 수 있도록 돕기 위해 저희 제품들을 개발하고 있습니다.