"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > JavaScript를 사용하여 푸시 알림 구현: 프로덕션 수준 접근 방식

JavaScript를 사용하여 푸시 알림 구현: 프로덕션 수준 접근 방식

2024-11-08에 게시됨
검색:771

Implementing Push Notifications Using JavaScript: A Production-Grade Approach

이 게시물에서는 프로덕션 수준 모범 사례에 따라 JavaScript를 사용하여 푸시 알림을 구현하는 방법을 알아봅니다. 가장 좋은 점 중 하나는 폴더 구조도 제공하여 프로젝트를 쉽게 설정할 수 있다는 것입니다.

실제 앱에서 푸시 알림을 설정하려면 신중한 계획이 필요합니다. 전문적인 Node.js 앱에서 이 기능을 구축하는 방법을 보여드리겠습니다. 코드를 구성하고, 보안을 유지하고, 앱이 성장하더라도 코드가 제대로 작동하는지 확인하는 방법과 같은 중요한 부분을 다룰 것입니다.

시작하려면 Node.js 서버에서 푸시 알림을 보내는 데 도움이 되는 라이브러리가 필요합니다. 웹 푸시 라이브러리는 알림을 보내고 필요한 키를 관리하는 도구를 제공합니다.

1. 푸시 알림: 프로젝트 구조

먼저 깔끔하고 확장 가능한 코드베이스를 유지하기 위해 프로젝트 구조를 설정해 보겠습니다.

/notification-service
├── /config
│   ├── default.js
│   └── production.js
├── /controllers
│   └── notificationController.js
├── /models
│   └── user.js
├── /routes
│   └── notificationRoutes.js
├── /services
│   ├── notificationService.js
│   ├── subscriptionService.js
│   └── webPushService.js
├── /utils
│   └── errorHandler.js
├── /tests
│   └── notification.test.js
├── app.js
├── package.json
├── .env
└── README.md

필수 NPM 패키지

구현을 시작하기 전에 다음 NPM 패키지가 설치되어 있는지 확인하세요.

  • express: 최소한의 유연한 Node.js 웹 애플리케이션 프레임워크입니다.
  • mongoose: MongoDB 및 Node.js용 ODM(객체 데이터 모델링) 라이브러리입니다.
  • web-push: 웹 푸시 프로토콜을 사용하여 푸시 알림을 보내기 위한 라이브러리입니다.
  • dotenv: .env 파일에서 환경 변수를 로드하는 종속성 없는 모듈입니다.
  • supertest: Node.js에서 HTTP 어설션을 테스트하기 위한 라이브러리입니다.

npm을 사용하여 다음 패키지를 설치합니다.

bash

npm install express mongoose web-push dotenv supertest

2. 푸시 알림: 프로젝트 구성

다양한 환경(예: 개발, 프로덕션)에 대한 구성 파일을 만듭니다. 이러한 파일은 환경별 설정을 저장합니다.

// /config/default.js
module.exports = {
    server: {
        port: 3000,
        env: 'development'
    },
    pushNotifications: {
        publicVapidKey: process.env.VAPID_PUBLIC_KEY,
        privateVapidKey: process.env.VAPID_PRIVATE_KEY,
        gcmApiKey: process.env.GCM_API_KEY
    },
    db: {
        uri: process.env.MONGO_URI
    }
};
// /config/production.js
module.exports = {
    server: {
        port: process.env.PORT || 3000,
        env: 'production'
    },
    // Same structure as default, with production-specific values
};

3. 데이터베이스 모델링

Mongoose를 사용하여 사용자 스키마 및 알림 구독을 정의합니다.

// /models/user.js
const mongoose = require('mongoose');

const subscriptionSchema = new mongoose.Schema({
    endpoint: String,
    keys: {
        p256dh: String,
        auth: String
    }
});

const userSchema = new mongoose.Schema({
    email: { type: String, required: true, unique: true },
    subscriptions: [subscriptionSchema],
    preferences: {
        pushNotifications: { type: Boolean, default: true }
    }
});

module.exports = mongoose.model('User', userSchema);

4. 알림 서비스

알림을 서비스로 처리하는 로직을 모듈화합니다.

// /services/webPushService.js
const webPush = require('web-push');
const config = require('config');

webPush.setVapidDetails(
    'mailto:[email protected]',
    config.get('pushNotifications.publicVapidKey'),
    config.get('pushNotifications.privateVapidKey')
);

module.exports = {
    sendNotification: async (subscription, payload) => {
        try {
            await webPush.sendNotification(subscription, JSON.stringify(payload));
        } catch (error) {
            console.error('Error sending notification', error);
        }
    }
};
// /services/notificationService.js
const User = require('../models/user');
const webPushService = require('./webPushService');

module.exports = {
    sendPushNotifications: async (userId, payload) => {
        const user = await User.findById(userId);
        if (user && user.preferences.pushNotifications) {
            user.subscriptions.forEach(subscription => {
                webPushService.sendNotification(subscription, payload);
            });
        }
    }
};

5. 컨트롤러 로직

API 경로를 처리하고 서비스를 통합합니다.

// /controllers/notificationController.js
const notificationService = require('../services/notificationService');

exports.sendNotification = async (req, res, next) => {
    try {
        const { userId, title, body } = req.body;
        const payload = { title, body };
        await notificationService.sendPushNotifications(userId, payload);
        res.status(200).json({ message: 'Notification sent successfully' });
    } catch (error) {
        next(error);
    }
};

6. 라우팅

API에 대한 경로를 설정합니다.

// /routes/notificationRoutes.js
const express = require('express');
const router = express.Router();
const notificationController = require('../controllers/notificationController');

router.post('/send', notificationController.sendNotification);

module.exports = router;

7. 오류 처리

앱이 충돌하지 않도록 오류 처리를 중앙 집중화합니다.

// /utils/errorHandler.js
module.exports = (err, req, res, next) => {
    console.error(err.stack);
    res.status(500).send({ error: 'Something went wrong!' });
};

8. 애플리케이션 진입점

애플리케이션을 초기화하고 데이터베이스에 연결합니다.

// app.js
const express = require('express');
const mongoose = require('mongoose');
const config = require('config');
const notificationRoutes = require('./routes/notificationRoutes');
const errorHandler = require('./utils/errorHandler');

const app = express();

app.use(express.json());
app.use('/api/notifications', notificationRoutes);
app.use(errorHandler);

mongoose.connect(config.get('db.uri'), {
    useNewUrlParser: true,
    useUnifiedTopology: true
})
    .then(() => console.log('MongoDB connected...'))
    .catch(err => console.error('MongoDB connection error:', err));

const PORT = config.get('server.port');
app.listen(PORT, () => console.log(`Server running in ${config.get('server.env')} mode on port ${PORT}`));

9. 보안 관행

  • 환경 변수: API 키 및 데이터베이스 URI와 같은 중요한 정보를 환경 변수에 저장합니다.
  • HTTPS: HTTPS를 통해 애플리케이션을 제공하여 클라이언트와 서버 간의 통신을 보호합니다.
  • 콘텐츠 보안 정책(CSP): XSS(교차 사이트 스크립팅) 공격을 방지하기 위해 CSP 헤더를 구현합니다.
  • 속도 제한: 무차별 대입 공격으로부터 API를 보호하려면 express-rate-limit와 같은 미들웨어를 사용하세요.

10. 테스트

다양한 조건에서 서비스가 예상대로 작동하는지 확인하는 테스트를 작성하세요.

// /tests/notification.test.js
const request = require('supertest');
const app = require('../app');

describe('Notification API', () => {
    it('should send a notification', async () => {
        const res = await request(app)
            .post('/api/notifications/send')
            .send({ userId: 'someUserId', title: 'Test', body: 'This is a test' });
        expect(res.statusCode).toEqual(200);
        expect(res.body.message).toBe('Notification sent successfully');
    });
});

11. 프로덕션에 배포

  • CI/CD 파이프라인: Jenkins, GitHub Actions 또는 GitLab CI와 같은 도구를 사용하여 CI/CD 파이프라인을 설정하여 애플리케이션 테스트, 구축 및 배포를 자동화합니다.
  • 컨테이너화: 애플리케이션을 Docker화하여 다양한 환경에서 일관성을 보장합니다.
  • 모니터링: Prometheus 및 Grafana와 같은 모니터링 도구를 사용하여 애플리케이션의 상태와 성능을 추적합니다.

12. 크기 조정

  • 수평 확장: 로드 밸런서 뒤에 서비스의 여러 인스턴스를 배포하여 높은 트래픽을 처리합니다.
  • 데이터베이스 확장: 데이터베이스의 수평 확장을 위해 MongoDB에서 샤딩 또는 복제본 세트를 구현합니다.

이 프로덕션 등급 설정은 푸시 알림 시스템의 확장성, 보안 및 유지 관리 가능성을 보장합니다. 코드는 업계 모범 사례에 따라 손쉬운 테스트, 배포 및 모니터링을 지원하도록 구성되어 있습니다. 추가 질문이 있거나 구체적인 구현 세부정보가 필요한 경우 언제든지 문의하세요!

릴리스 선언문 이 기사는 https://dev.to/shanu001x/implementing-push-notifications-using-javascript-a-production-grade-approach-1nmf?1에서 복제됩니다. 침해가 있는 경우, [email protected]으로 문의해 주십시오. 그것을 삭제하려면
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3