Takip et

Ölçeklenebilir Gerçek Zamanlı Bir İş Kurulu Oluşturmak: React, Node.js ve Google Kimlik Doğrulaması ile

Ölçeklenebilir Gerçek Zamanlı Bir İş Kurulu Oluşturmak: React, Node.js ve Google Kimlik Doğrulaması ile

Merhaba, bu makalede React, Node.js ve Google Kimlik Doğrulaması kullanarak ölçeklenebilir, gerçek zamanlı bir iş kurulu oluşturma sürecini adım adım ele alacağız. Bu makale, teknoloji meraklıları ve deneyimli geliştiriciler için bir rehber görevi görecektir.

Neden Gerçek Zamanlı Bir İş Kurulu?

Geleneksel iş kurullarının aksine, gerçek zamanlı bir iş kurulu, iş arayanların ve işverenlerin gerçek zamanlı olarak iletişim kurmasına olanak tanır. Bu, yeni iş ilanlarının anında yayınlanmasını, adayların başvurularını hemen göndermesini ve işverenlerin uygun adaylarla anında iletişime geçmesini sağlar. Bu özellik, hem iş arayanlar için zaman kazandırır hem de işverenler için verimlilik sağlar.

Projenin Temel Bileşenleri

Projemizde aşağıdaki temel bileşenleri kullanacağız:

  • **React:** Kullanıcı arayüzünü oluşturmak için kullanacağımız bir JavaScript kitaplığı.
  • **Node.js:** Sunucu tarafı geliştirme için kullanacağımız JavaScript çalışma zamanı.
  • **Express.js:** Node.js için bir web uygulaması çerçevesi.
  • **MongoDB:** Veri depolama için kullanacağımız bir NoSQL veritabanı.
  • **Socket.IO:** Gerçek zamanlı iletişim sağlamak için kullanacağımız bir JavaScript kütüphanesi.
  • **Google Kimlik Doğrulaması:** Kullanıcı kimlik doğrulaması için kullanacağımız bir hizmet.

Proje Yapısı

Proje yapımız aşağıdaki gibi olacaktır:

job-board/
├── client/
│   ├── src/
│   │   ├── components/
│   │   │   ├── JobCard.js
│   │   │   ├── JobList.js
│   │   │   ├── LoginForm.js
│   │   │   ├── SignupForm.js
│   │   │   ├── Navbar.js
│   │   │   └── Footer.js
│   │   ├── App.js
│   │   ├── services/
│   │   │   ├── auth.js
│   │   │   ├── job.js
│   │   ├── utils/
│   │   │   ├── axios.js
│   │   ├── styles/
│   │   │   ├── App.css
│   │   ├── index.js
│   ├── public/
│   │   ├── index.html
│   │   └── manifest.json
│   └── webpack.config.js
└── server/
    ├── index.js
    ├── config/
    │   └── database.js
    ├── models/
    │   ├── Job.js
    │   └── User.js
    ├── routes/
    │   ├── auth.js
    │   ├── job.js
    │   └── user.js
    ├── services/
    │   ├── auth.js
    │   ├── job.js
    │   └── user.js
    └── sockets/
        └── index.js

Adım 1: Projenin Kurulması

Projenin temel yapısını oluşturmak için aşağıdaki adımları izleyeceğiz:

  1. Yeni bir proje dizini oluşturun: mkdir job-board
  2. Proje dizinine gidin: cd job-board
  3. İstemci tarafı projesini oluşturun: npx create-react-app client
  4. Sunucu tarafı projesini oluşturun: mkdir server
  5. Sunucu tarafı projesi için gerekli paketleri yükleyin: npm install express mongoose socket.io cors dotenv

Adım 2: Veritabanı Kurulumu

MongoDB’yi veri depolama için kullanacağız. MongoDB’yi kurmak için aşağıdaki adımları izleyin:

  1. MongoDB’yi indirin ve kurun.
  2. MongoDB’yi başlatın: mongod
  3. MongoDB’ye bağlanın: mongo
  4. Bir veritabanı oluşturun: use jobboard
  5. Bir koleksiyon oluşturun: db.jobs.insertOne({})

Adım 3: Modellerin Tanımlanması

Veritabanımızda kullanılacak modelleri tanımlayacağız. server/models dizininde Job.js ve User.js dosyaları oluşturun.

Job Model

const mongoose = require('mongoose');

const jobSchema = new mongoose.Schema({
  title: { type: String, required: true },
  company: { type: String, required: true },
  location: { type: String, required: true },
  description: { type: String, required: true },
  createdAt: { type: Date, default: Date.now },
});

module.exports = mongoose.model('Job', jobSchema);

User Model

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
  name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true },
  role: { type: String, default: 'user' },
  createdAt: { type: Date, default: Date.now },
});

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

Adım 4: Sunucu Tarafı Kodunu Yazma

Sunucu tarafı kodunu yazmaya başlayalım. server/index.js dosyasını düzenleyeceğiz.

const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const dotenv = require('dotenv');
const http = require('http');
const socketIO = require('socket.io');

const authRoutes = require('./routes/auth');
const jobRoutes = require('./routes/job');
const userRoutes = require('./routes/user');

const app = express();
dotenv.config();

// Veritabanına bağlanma
mongoose.connect(process.env.DATABASE_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
})
  .then(() => console.log('Veritabanına bağlanıldı.'))
  .catch(err => console.error(err));

// Ortam ayarları
app.use(cors());
app.use(express.json());

// Rota tanımlamaları
app.use('/api/auth', authRoutes);
app.use('/api/jobs', jobRoutes);
app.use('/api/users', userRoutes);

// Sunucu başlatma
const server = http.createServer(app);
const io = socketIO(server, {
  cors: {
    origin: 'http://localhost:3000',
    methods: ['GET', 'POST'],
  },
});

io.on('connection', (socket) => {
  console.log('Bir kullanıcı bağlandı.');

  // Yeni iş ilanı eklendiğinde soket üzerinden yayın yapma
  socket.on('new-job', (job) => {
    io.emit('new-job', job);
  });

  socket.on('disconnect', () => {
    console.log('Bir kullanıcı bağlantısını kesti.');
  });
});

// Sunucuyu başlatma
const port = process.env.PORT || 5000;
server.listen(port, () => console.log(`Sunucu ${port} portunda çalışıyor.`));

Adım 5: Rota Tanımlamaları

Kullanıcı kimlik doğrulaması, iş ilanları ve kullanıcılarla ilgili işlemleri ele alacak rotaları tanımlayacağız. server/routes dizininde auth.js, job.js ve user.js dosyaları oluşturun.

Auth Routes

const express = require('express');
const router = express.Router();
const authController = require('../controllers/auth');

// Kayıt olma
router.post('/signup', authController.signup);

// Giriş yapma
router.post('/login', authController.login);

module.exports = router;

Job Routes

const express = require('express');
const router = express.Router();
const jobController = require('../controllers/job');

// Tüm iş ilanlarını listeleme
router.get('/', jobController.getJobs);

// Yeni iş ilanı ekleme
router.post('/', jobController.createJob);

// Belirli bir iş ilanını alma
router.get('/:id', jobController.getJob);

// İş ilanını güncelleme
router.put('/:id', jobController.updateJob);

// İş ilanını silme
router.delete('/:id', jobController.deleteJob);

module.exports = router;

User Routes

const express = require('express');
const router = express.Router();
const userController = require('../controllers/user');

// Tüm kullanıcıları listeleme
router.get('/', userController.getUsers);

// Belirli bir kullanıcıyı alma
router.get('/:id', userController.getUser);

// Kullanıcı bilgilerini güncelleme
router.put('/:id', userController.updateUser);

// Kullanıcıyı silme
router.delete('/:id', userController.deleteUser);

module.exports = router;

Adım 6: Denetleyicilerin Tanımlanması

Rotalar için gerekli iş mantığını içeren denetleyicileri tanımlayacağız. server/controllers dizininde auth.js, job.js ve user.js dosyaları oluşturun.

Auth Controller

const User = require('../models/User');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');

// Kayıt olma
exports.signup = async (req, res) => {
  try {
    const { name, email, password } = req.body;

    // Kullanıcı adı ve e-posta adresi zaten mevcut mu kontrol et
    const existingUser = await User.findOne({ email });
    if (existingUser) {
      return res.status(400).json({ message: 'Kullanıcı adı veya e-posta adresi zaten mevcut.' });
    }

    // Şifreyi hashleyin
    const hashedPassword = await bcrypt.hash(password, 10);

    // Yeni kullanıcı kaydı oluşturun
    const newUser = new User({ name, email, password: hashedPassword });
    await newUser.save();

    // JWT oluşturun
    const token = jwt.sign({ userId: newUser._id }, process.env.JWT_SECRET);

    res.status(201).json({ token, userId: newUser._id });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Bir hata oluştu.' });
  }
};

// Giriş yapma
exports.login = async (req, res) => {
  try {
    const { email, password } = req.body;

    // Kullanıcıyı bulun
    const user = await User.findOne({ email });
    if (!user) {
      return res.status(401).json({ message: 'Geçersiz e-posta adresi veya şifre.' });
    }

    // Şifreyi doğrulayın
    const isMatch = await bcrypt.compare(password, user.password);
    if (!isMatch) {
      return res.status(401).json({ message: 'Geçersiz e-posta adresi veya şifre.' });
    }

    // JWT oluşturun
    const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET);

    res.status(200).json({ token, userId: user._id });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Bir hata oluştu.' });
  }
};

Job Controller

const Job = require('../models/Job');

// Tüm iş ilanlarını listeleme
exports.getJobs = async (req, res) => {
  try {
    const jobs = await Job.find().sort({ createdAt: -1 });
    res.status(200).json(jobs);
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Bir hata oluştu.' });
  }
};

// Yeni iş ilanı ekleme
exports.createJob = async (req, res) => {
  try {
    const { title, company, location, description } = req.body;

    // Yeni iş ilanı oluşturun
    const newJob = new Job({ title, company, location, description });
    await newJob.save();

    // Yeni iş ilanını soket üzerinden yayınlayın
    io.emit('new-job', newJob);

    res.status(201).json(newJob);
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Bir hata oluştu.' });
  }
};

// Belirli bir iş ilanını alma
exports.getJob = async (req, res) => {
  try {
    const job = await Job.findById(req.params.id);
    if (!job) {
      return res.status(404).json({ message: 'İş ilanı bulunamadı.' });
    }
    res.status(200).json(job);
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Bir hata oluştu.' });
  }
};

// İş ilanını güncelleme
exports.updateJob = async (req, res) => {
  try {
    const { title, company, location, description } = req.body;
    const updatedJob = await Job.findByIdAndUpdate(
      req.params.id,
      { title, company, location, description },
      { new: true },
    );
    if (!updatedJob) {
      return res.status(404).json({ message: 'İş ilanı bulunamadı.' });
    }
    res.status(200).json(updatedJob);
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Bir hata oluştu.' });
  }
};

// İş ilanını silme
exports.deleteJob = async (req, res) => {
  try {
    const deletedJob = await Job.findByIdAndDelete(req.params.id);
    if (!deletedJob) {
      return res.status(404).json({ message: 'İş ilanı bulunamadı.' });
    }
    res.status(200).json({ message: 'İş ilanı silindi.' });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Bir hata oluştu.' });
  }
};

User Controller

const User = require('../models/User');

// Tüm kullanıcıları listeleme
exports.getUsers = async (req, res) => {
  try {
    const users = await User.find();
    res.status(200).json(users);
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Bir hata oluştu.' });
  }
};

// Belirli bir kullanıcıyı alma
exports.getUser = async (req, res) => {
  try {
    const user = await User.findById(req.params.id);
    if (!user) {
      return res.status(404).json({ message: 'Kullanıcı bulunamadı.' });
    }
    res.status(200).json(user);
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Bir hata oluştu.' });
  }
};

// Kullanıcı bilgilerini güncelleme
exports.updateUser = async (req, res) => {
  try {
    const { name, email, password } = req.body;
    const updatedUser = await User.findByIdAndUpdate(
      req.params.id,
      { name, email, password },
      { new: true },
    );
    if (!updatedUser) {
      return res.status(404).json({ message: 'Kullanıcı bulunamadı.' });
    }
    res.status(200).json(updatedUser);
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Bir hata oluştu.' });
  }
};

// Kullanıcıyı silme
exports.deleteUser = async (req, res) => {
  try {
    const deletedUser = await User.findByIdAndDelete(req.params.id);
    if (!deletedUser) {
      return res.status(404).json({ message: 'Kullanıcı bulunamadı.' });
    }
    res.status(200).json({ message: 'Kullanıcı silindi.' });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Bir hata oluştu.' });
  }
};

Adım 7: İstemci Tarafı Kodunu Yazma

İstemci tarafı kodunu yazmaya başlayalım. client/src dizininde App.js dosyasını düzenleyeceğiz.

import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import JobList from './components/JobList';
import JobDetails from './components/JobDetails';
import LoginForm from './components/LoginForm';
import SignupForm from './components/SignupForm';
import Navbar from './components/Navbar';
import Footer from './components/Footer';
import AuthContext from './context/AuthContext';
import axios from './utils/axios';

function App() {
  const [authTokens, setAuthTokens] = useState(null);
  const [user, setUser] = useState(null);

  const setTokens = (data) => {
    localStorage.setItem('tokens', JSON.stringify(data));
    setAuthTokens(data);
  };

  const getUser = async () => {
    const response = await axios.get('/api/users/me', {
      headers: {
        Authorization: `Bearer ${authTokens.access_token}`,
      },
    });
    setUser(response.data);
  };

  useEffect(() => {
    const tokens = JSON.parse(localStorage.getItem('tokens'));
    if (tokens) {
      setTokens(tokens);
      getUser();
    }
  }, []);

  const logout = () => {
    localStorage.removeItem('tokens');
    setAuthTokens(null);
    setUser(null);
  };

  return (
    
      
        
        
          } />
          } />
          } />
          } />
        
        
); } export default App;

Adım 8: Google Kimlik Doğrulaması

Google Kimlik Doğrulaması’nı kullanarak kullanıcıların giriş yapmasını ve kaydolmasını sağlayacağız.

  1. Google Cloud Console’da bir proje oluşturun.
  2. Proje için OAuth 2.0 kimlik bilgisi oluşturun.
    • Uygulama türü: Web uygulaması
    • Yetkilendirme URL’si: http://localhost:3000/api/auth/google/callback
    • Onaylanmış köken URL’si: http://localhost:3000
    • Gelişmiş ayarlar:
      • JWT yayınlayıcısı: Google’ın yayınlayıcısını seçin.
      • JWT alıcısı: YOUR_CLIENT_ID.apps.googleusercontent.com
  3. Google Kimlik Doğrulaması kimlik bilgilerini server/config/database.js dosyasında saklayın.
  4. Sunucu tarafında Google Kimlik Doğrulaması için rotaları ayarlayın.
  5. İstemci tarafında Google Kimlik Doğrulaması için kütüphaneyi kullanarak Google’a giriş yapma seçeneği ekleyin.

Adım 9: Gerçek Zamanlı İşlevselliği Uygulama

Socket.IO kullanarak gerçek zamanlı işlevselliği uygulayacağız. server/sockets/index.js dosyasını düzenleyerek yeni iş ilanları eklendiğinde gerçek zamanlı güncellemeleri ileteceğiz.

Adım 10: Ölçeklenebilirlik

Projenin ölçeklenebilirliğini artırmak için aşağıdaki ipuçlarını kullanabilirsiniz:

  • **Veritabanı ölçekleme:** MongoDB’de sharding ve replica setleri kullanarak veritabanını ölçekleyebilirsiniz.
  • **Sunucu tarafı ölçekleme:** Sunucuyu Node.js cluster modunu veya bir yük dengeleyici kullanarak ölçekleyebilirsiniz.
  • **İstemci tarafı performans optimizasyonu:** İstemci tarafı performansını artırmak için React’in özelliklerini kullanın.
  • **İstemci tarafı önbellekleme:** İstemci tarafında önbellekleme kullanarak sunucuya yapılan istek sayısını azaltabilirsiniz.

Sonuç

Bu makalede, React, Node.js ve Google Kimlik Doğrulaması kullanarak ölçeklenebilir, gerçek zamanlı bir iş kurulu oluşturma sürecini adım adım ele aldık. Projede kullanılan teknolojileri ve tasarım desenlerini derinlemesine inceleyerek projenin yapı taşlarını oluşturduk.

Bu projede, gerçek zamanlı işlevsellik, Google Kimlik Doğrulaması ve ölçeklenebilirlik gibi önemli konulara değinildi. Bu makaleyi bir başlangıç noktası olarak kabul ederek projenizi kendi ihtiyaçlarınıza göre özelleştirebilirsiniz. Daha fazla bilgi ve örnek için fatihsoysal.com sitesini ziyaret edebilirsiniz.

Umarım bu makale, kendi gerçek zamanlı iş kurulunuzu oluşturmanıza yardımcı olur! Başarılar!

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.