이 게시물에서는 프로덕션 수준 모범 사례에 따라 JavaScript를 사용하여 푸시 알림을 구현하는 방법을 알아봅니다. 가장 좋은 점 중 하나는 폴더 구조도 제공하여 프로젝트를 쉽게 설정할 수 있다는 것입니다.
실제 앱에서 푸시 알림을 설정하려면 신중한 계획이 필요합니다. 전문적인 Node.js 앱에서 이 기능을 구축하는 방법을 보여드리겠습니다. 코드를 구성하고, 보안을 유지하고, 앱이 성장하더라도 코드가 제대로 작동하는지 확인하는 방법과 같은 중요한 부분을 다룰 것입니다.
시작하려면 Node.js 서버에서 푸시 알림을 보내는 데 도움이 되는 라이브러리가 필요합니다. 웹 푸시 라이브러리는 알림을 보내고 필요한 키를 관리하는 도구를 제공합니다.
먼저 깔끔하고 확장 가능한 코드베이스를 유지하기 위해 프로젝트 구조를 설정해 보겠습니다.
/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 패키지가 설치되어 있는지 확인하세요.
bash npm install express mongoose web-push dotenv supertest
다양한 환경(예: 개발, 프로덕션)에 대한 구성 파일을 만듭니다. 이러한 파일은 환경별 설정을 저장합니다.
// /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 };
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);
알림을 서비스로 처리하는 로직을 모듈화합니다.
// /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); }); } } };
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); } };
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;
앱이 충돌하지 않도록 오류 처리를 중앙 집중화합니다.
// /utils/errorHandler.js module.exports = (err, req, res, next) => { console.error(err.stack); res.status(500).send({ error: 'Something went wrong!' }); };
애플리케이션을 초기화하고 데이터베이스에 연결합니다.
// 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}`));
다양한 조건에서 서비스가 예상대로 작동하는지 확인하는 테스트를 작성하세요.
// /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'); }); });
이 프로덕션 등급 설정은 푸시 알림 시스템의 확장성, 보안 및 유지 관리 가능성을 보장합니다. 코드는 업계 모범 사례에 따라 손쉬운 테스트, 배포 및 모니터링을 지원하도록 구성되어 있습니다. 추가 질문이 있거나 구체적인 구현 세부정보가 필요한 경우 언제든지 문의하세요!
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3