Page ▾
[ Cafe24 서버 호스팅 ] #5: Angular - Node.js 기본 API 연동 & CRUD 예제 소스

✨ 목표

Angular와 Node.js(Express)를 활용해 간단한 CRUD API를 구현하고, 이를 Cafe24 서버에 배포하여 프론트엔드와 백엔드 API가 연동되는 전체 구조를 구축하는 과정을 다룹니다.

 

📦 주요 작업 요약

  1. Angular 프로젝트에서 HTTP 클라이언트로 Node.js API 연동
  2. Node.js(Express) 서버 구축 및 API 라우터 구현
  3. Angular 빌드 후 정적 파일을 Express에서 서비스하도록 구성
  4. FileZilla를 사용해 Cafe24 서버에 업로드
  5. MobaXterm에서 PM2 또는 Node 명령어로 서버 실행
  6. 외부 접속으로 프론트엔드-백엔드 연동 정상 작동 확인

✔️ 1. Angular 프로젝트 설정 및 API 연동

  • VSCode에서 프로젝트 폴더(myPrj)를 열고, 해당 경로에 예제 코드에 맞춰 필요한 폴더 및 파일을 생성합니다.

 

1️⃣ Angular HTTP 클라이언트 설정

 

Angular는 HttpClientModule을 사용하여 외부 API와 통신합니다. 먼저, app.module.ts에 해당 모듈을 등록해야 합니다.

 

📄 src/app/app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
import { UserListComponent } from './components/user-list/user-list.component';
import { FormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent,
    UserListComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    HttpClientModule  // ✅ API 호출을 위한 HttpClientModule 등록
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

 

📄 src/app/app.component.html

<div>
  <h1>Angular + Node.js API 통신 예제</h1>
  <app-user-list></app-user-list>
</div>

 

2️⃣ 사용자 데이터 인터페이스 정의

 

API에서 사용하는 사용자 데이터를 타입스크립트 인터페이스로 정의합니다.


📄 src/app/models/user.ts

export interface User {
  id: number;
  name: string;
  email: string;
}

 

3️⃣ 사용자 API 서비스 작성

 

Node.js 서버와 통신하기 위한 API 서비스 파일을 생성합니다. HttpClient를 이용해 CRUD 기능을 구현합니다.


📄 src/app/services/user.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { User } from '../models/user';

@Injectable({
  providedIn: 'root'
})
export class UserService {
  private apiUrl = 'http://localhost:3000/api/users';

  constructor(private http: HttpClient) { }
	
  // 모든 사용자 가져오기
  getUsers(): Observable<User[]> {
    return this.http.get<User[]>(this.apiUrl);
  }

  // 특정 사용자 가져오기
  getUser(id: number): Observable<User> {
    return this.http.get<User>(`${this.apiUrl}/${id}`);
  }

  // 새 사용자 추가
  addUser(user: Omit<User, 'id'>): Observable<User> {
    return this.http.post<User>(this.apiUrl, user);
  }

  // 사용자 정보 수정
  updateUser(id: number, user: Partial<User>): Observable<User> {
    return this.http.put<User>(`${this.apiUrl}/${id}`, user);
  }

  // 사용자 삭제
  deleteUser(id: number): Observable<User> {
    return this.http.delete<User>(`${this.apiUrl}/${id}`);
  }
}

 

4️⃣ 사용자 컴포넌트 생성 및 템플릿 작성

 

Angular 프로젝트에서 사용자 데이터를 CRUD 하는 UI를 처리할 컴포넌트를 생성합니다.

 

⭐️ 컴포넌트 생성 명령어:

C:\myPrj\client\src\app>
ng g c components/user-list


📄 src/app/components/user-list/user-list.component.ts

import { Component, OnInit } from '@angular/core';
import { User } from '../../models/user';
import { UserService } from '../../services/user.service';

@Component({
  selector: 'app-user-list',
  templateUrl: './user-list.component.html',
  styleUrls: ['./user-list.component.css']
})
export class UserListComponent implements OnInit {
  users: User[] = [];
  newUser = { name: '', email: '' };
  selectedUser: User | null = null;

  constructor(private userService: UserService) { }

  ngOnInit(): void {
    this.loadUsers();
  }

  loadUsers(): void {
    this.userService.getUsers()
      .subscribe(users => this.users = users);
  }

  addUser(): void {
    if (this.newUser.name && this.newUser.email) {
      this.userService.addUser(this.newUser)
        .subscribe(user => {
          this.users.push(user);
          this.newUser = { name: '', email: '' };
        });
    }
  }

  selectUser(user: User): void {
    this.selectedUser = { ...user };
  }

  updateUser(): void {
    if (this.selectedUser) {
      this.userService.updateUser(this.selectedUser.id, this.selectedUser)
        .subscribe(updatedUser => {
          const index = this.users.findIndex(u => u.id === updatedUser.id);
          if (index !== -1) {
            this.users[index] = updatedUser;
          }
          this.selectedUser = null;
        });
    }
  }

  deleteUser(id: number): void {
    this.userService.deleteUser(id)
      .subscribe(() => {
        this.users = this.users.filter(user => user.id !== id);
        if (this.selectedUser && this.selectedUser.id === id) {
          this.selectedUser = null;
        }
      });
  }

  cancelEdit(): void {
    this.selectedUser = null;
  }
}

 

 

📄 src/app/components/user-list/user-list.component.html

<div class="container">
  <h2>사용자 목록</h2>

  <!-- 사용자 추가 폼 -->
  <div class="add-form">
    <h3>새 사용자 추가</h3>
    <div>
      <input type="text" placeholder="이름" [(ngModel)]="newUser.name">
    </div>
    <div>
      <input type="email" placeholder="이메일" [(ngModel)]="newUser.email">
    </div>
    <button (click)="addUser()">추가</button>
  </div>

  <!-- 사용자 목록 -->
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>이름</th>
        <th>이메일</th>
        <th>작업</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let user of users">
        <td>{{ user.id }}</td>
        <td>{{ user.name }}</td>
        <td>{{ user.email }}</td>
        <td>
          <button (click)="selectUser(user)">수정</button>
          <button (click)="deleteUser(user.id)">삭제</button>
        </td>
      </tr>
    </tbody>
  </table>

  <!-- 사용자 수정 폼 -->
  <div *ngIf="selectedUser" class="edit-form">
    <h3>사용자 수정</h3>
    <div>
      <input type="text" placeholder="이름" [(ngModel)]="selectedUser.name">
    </div>
    <div>
      <input type="email" placeholder="이메일" [(ngModel)]="selectedUser.email">
    </div>
    <button (click)="updateUser()">저장</button>
    <button (click)="cancelEdit()">취소</button>
  </div>
</div>

 

📌 environments가 없다면, 추후에 작업을 위해 추가

 

environments 폴더를 생성하고, 개발 환경 및 프로덕션 환경 파일을 작성할 수 있습니다.

 

📄 src/environments/environment.ts:

export const environment = {
  production: false,
  apiUrl: 'http://localhost:3000/api'  // 개발용 API URL
};

 

📄 src/environments/environment.prod.ts:

export const environment = {
  production: true,
  apiUrl: 'https://your-production-api-url.com/api'  // 배포용 API URL
};

 

📁 최종 client 디렉터리 구조 예시:

client/
├── src/
│      ├── app/
│      │      ├── components/
│      │      │ └── user-list/
│      │      │ ├── user-list.component.ts
│      │      │ ├── user-list.component.html
│      │      │ └── user-list.component.css
│      │      ├── models/
│      │      │ └── user.ts
│      │      ├── services/
│      │      │ └── user.service.ts
│      │      ├── app.routing.module.ts
│      │      ├── app.component.css
│      │      ├── app.component.html
│      │      ├── app.component.spec.ts
│      │      ├── app.component.ts
│      │      └── app.module.ts
│      ├── assets/
│      ├── environments/
│      │      ├── environment.ts
│      │      └── environment.prod.ts
│      ├── index.html
│      ├── main.ts
│      └── styles.css
├── angular.json
├── package.json
└── node_modules/

 

✅ Angular 프론트엔드 실행 테스트 (ng serve)

 

프론트엔드 코드 구조를 다 만들었다면, 로컬에서 정상적으로 화면이 뜨는지 먼저 확인해 보는 것이 좋습니다.

 

1. client 폴더를 통합 터미널에서 열기

C:\myPrj\client>

 

2. 필요한 패키지 설치

npm install

 

3. 개발 서버 실행

ng serve

 

4. 브라우저에서 확인

 

아래 주소로 접속하면 Angular 앱이 실행됩니다:

http://localhost:4200

 

  • 아무 에러 없이, 만들어둔 컴포넌트 화면이 보이면 성공입니다.
  • 만약 오류가 난다면 콘솔의 에러 메시지를 확인하고, 빠진 파일이나 오타가 없는지 다시 확인하세요.

 

컴포넌트 화면

 


✔️ 2. Node.js(Express) 서버 구성

  • Node.js는 백엔드 API 서버로, Angular와 통신하며 사용자 데이터를 처리합니다. 여기서는 간단한 Express 기반 서버를 하나의 파일(server.js)로 구성합니다.

 

1️⃣ server.js 작성


📄 server.js

const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');

const app = express();
const PORT = 3000;

// CORS 설정 (Angular 앱에서 API 호출 허용)
app.use(cors());

// JSON 요청 바디 파싱
app.use(bodyParser.json());

// 샘플 데이터
let users = [
  { id: 1, name: '홍길동', email: 'hong@example.com' },
  { id: 2, name: '김철수', email: 'kim@example.com' },
  { id: 3, name: '이영희', email: 'lee@example.com' }
];

// GET - 모든 사용자 조회
app.get('/api/users', (req, res) => {
  res.json(users);
});

// GET - 특정 사용자 조회
app.get('/api/users/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const user = users.find(user => user.id === id);
  
  if (user) {
    res.json(user);
  } else {
    res.status(404).json({ message: '사용자를 찾을 수 없습니다.' });
  }
});

// POST - 사용자 추가
app.post('/api/users', (req, res) => {
  const newUser = {
    id: users.length > 0 ? Math.max(...users.map(user => user.id)) + 1 : 1,
    name: req.body.name,
    email: req.body.email
  };
  
  users.push(newUser);
  res.status(201).json(newUser);
});

// PUT - 사용자 정보 수정
app.put('/api/users/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const index = users.findIndex(user => user.id === id);
  
  if (index !== -1) {
    users[index] = { ...users[index], ...req.body };
    res.json(users[index]);
  } else {
    res.status(404).json({ message: '사용자를 찾을 수 없습니다.' });
  }
});

// DELETE - 사용자 삭제
app.delete('/api/users/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const index = users.findIndex(user => user.id === id);
  
  if (index !== -1) {
    const deletedUser = users[index];
    users = users.filter(user => user.id !== id);
    res.json(deletedUser);
  } else {
    res.status(404).json({ message: '사용자를 찾을 수 없습니다.' });
  }
});

// 서버 시작
app.listen(PORT, () => {
  console.log(`서버가 http://localhost:${PORT} 에서 실행 중입니다.`);
});

 

✅ Node.js(Express) 백엔드 서버 실행 테스트  (node server.js)

 

1. server 폴더를 통합 터미널에서 열기

C:\myPrj\server>

 

2. 한 번만 필요한 패키지 설치 (이미 설치했다면 생략 가능)

npm install express cors body-parser

 

3. 서버 실행

node server.js

 

4. 성공 메시지 확인

 

서버가 http://localhost:3000 에서 실행 중입니다.

 

5. 브라우저 테스트

http://localhost:3000/api/users

접속하면 JSON 형식의 사용자 목록이 출력됩니다.

 


💡 추가 팁

  • 백엔드 배포 전에 server.js 내 포트 번호를 80으로 바꾸면 도메인만으로 접속 가능 (http://도메인/api/...)

✨ 여기까지 Angular 에서 Node.js API와 연동하는 기본 구조를 만들었습니다.
다음 글에서는 Express 기반의 Node.js API 서버를 구축하고, Cafe24 서버에 배포하여 연동까지.