hetajs-mvc | 유저 CRUD 기능 구현하기

가연우·2022년 8월 17일
0

hetamvc(Java Script)

목록 보기
2/2

참고하세요!!
🔗 HetaMVC란?
🔗 프로젝트 깃허브 주소


🎨 유저 CRUD란?

유저와 관련된 CRUD 기능을 구현하는 것을 뜻합니다. CRUD는 각각 Create, Read, Update, Delete의 앞글자를 딴 줄임말로 무언가를 생성하고, 조회하고, 수정하고, 삭제하는 것을 말합니다. 즉 유저 CRUD는 유저를 생성하고, 조회하고, 수정하고, 삭제하는 것입니다.


🎈 API 명세서

유저 생성
[POST] /users

request

{
	"name" : "hello",
  	"age" : 11
}

response

{
	"id" : 1,
    "name" : "hello",
    "age" : 11
}

유저 수정
[PUT] /users/{userId}

request

{
	"name" : "bye",
  	"age" : 11
}

response

{
	"id" : 1,
  	"name" : "bye",
  	"age" : 11
}

유저 전체 조회
[GET] /users

response

[
  {
  	"id" : 1,
    "name" : "hello",
    "age" : 11
  },
  {
  	"id" : 2,
    "name" : "node",
    "age" : 100
  },
  
  ...
]

유저 상세 조회
[GET] /users/{userId}

response

{
	"id" : 1,
  	"name" : "hello",
  	"age" : 11
}

유저 삭제
[DELETE] /users/{userId}

response

[
  {
  	"id" : 2,
    "name" : "node",
    "age" : 100
  },
  
  ...
]

🎈 유저 모델

id
type : unsigned int
primary key, auto increment

name
type : string(20)
not null

age
type : unsinged int
not null


🎈 프로젝트 세팅

프로젝트 생성법
1. cmd 실행
2. 폴더 생성
3. 폴더 안에서 npx hetajs-mvc 명령어 입력
4. npm start로 서버 실행
5. http://localhost:5000 접속

  • 프로젝트에 들어가면 기본적인 세팅이 모두 완료되어 있고, 필요한 모듈들도 설치되어 있습니다.
  • 프로젝트를 실행해 http://localhost:5000 에 접속하거나, 해당 프로젝트의 readMe 파일을 보면 어노테이션들의 설명과 사용법이 설명되어 있습니다.

기본적으로 프로젝트를 생성하면 프로젝트 안에는 이미 많은 파일들이 세팅되어 있습니다. 따라서 현재 프로젝트를 위해 필요한 파일을 제외하고 모두 삭제하였습니다.


🧵 Model 정의하기

src/backend/user/model/UserModel.js

import {HetaSequelize} from 'hetamvc'

/** @Model */
export default class UserModel extends HetaSequelize {
    init(Sequelize, options) {
        return this.model('user', {
                id: {
                    type: Sequelize.INTEGER.UNSIGNED,
                    primaryKey: true,
                    autoIncrement: true
                },
                name: {
                    type: Sequelize.STRING(20),
                    allowNull: false
                },
                age: {
                    type: Sequelize.INTEGER.UNSIGNED, 
                  	allowNull: false
                }
            },
            options
        );
    }

    static associate(models) {
    }
}
  • Sequelize를 통해 Model을 생성하기 위해 hetamvc의 HetaSequelize를 import 받습니다.
  • 기본적으로 HetaMVC는 class를 통해 구현합니다. import 받은 HetaSequelize를 통해 class를 확장하여 Model을 정의합니다.
  • Model를 정의할 때는 @Model 어노테이션을 사용합니다. class 상단에 작성하며 반드시 /** */ 주석 안에 사용해야합니다.
  • 그 외 문법은 Nodejs에서 사용하는 Sequelize를 통한 Model 정의하는 방법과 동일합니다.
  • options은 index를 정의할 때 사용합니다. (아직 그외의 용도를 찾지 못했습니다..)


🧵 유저 생성하기 - Create

service
src/backend/user/controller/UserService.js

/** @Service */
export class UserService {
    constructor() {
        /** @Inject('UserModel')*/
        this.userModel;
    }

    //유저 생성
    /** @Transactional */
    createUser(name, age) {
        try {
            const user = this.userModel.create({
                name: name,
                age: age
            });
            return user;
        } catch (e) {
            console.error(e);
        }
    }
}

controller
src/backend/user/controller/UserService.js

/** @Controller*/
/** @RequestMapping ('/users') */
export class UserController {
    constructor() {
        /** @Inject('UserService')*/
        this.userService;
    }

    //유저 생성
    /** @RequestMapping('/', post) */
    createUser(req, res) {
        const name = req.body.name;
        const age = req.body.age * 1;
        const user = this.userService.createUser(name, age);
        res.send(user);
    }
}

🧵 유저 상세 조회하기 - Read

Service
src/backend/user/service/UserService.js

/** @Service */
export class UserService {
    constructor() {
        /** @Inject('UserModel')*/
        this.userModel;
    }

    //유저 상세 조회
    /** @Transactional */
    getUserById(id) {
        try {
            return this.userModel.findByPk(id);
        } catch (e) {
            console.error(e);
        }
    }
}

Controller
src/backend/user/controller/UserController.js

/** @Controller*/
/** @RequestMapping ('/users') */
export class UserController {
    constructor() {
        /** @Inject('UserService')*/
        this.userService;
    }

    //유저 상세 조회
    /** @RequestMapping('/:userId', get) */
    findUser(req, res){
        const userId = req.params.userId;
        const user = this.userService.getUserById(userId);

        res.send(user);
    }
}

🧵 유저 전체 조회하기 - Read

Service
src/backend/user/service/UserService.js

/** @Service */
export class UserService {
    constructor() {
        /** @Inject('UserModel')*/
        this.userModel;
    }

    //유저 목록 조회
    /** @Transactional */
    getUsers() {
        try {
            return this.userModel.findAll();
        } catch (e) {
            console.error(e);
        }
    }
}

Controller
src/backend/user/controller/UserController.js

/** @Controller*/
/** @RequestMapping ('/users') */
export class UserController {
    constructor() {
        /** @Inject('UserService')*/
        this.userService;
    }

    //유저 목록 조회
    /** @RequestMapping('/', get)*/
    findAllUser(req, res){
        const list = this.userService.getUsers();
        res.send(list);
    }
}

🧵 유저 수정하기 - Update

Service
src/backend/user/service/UserService.js

/** @Service */
export class UserService {
    constructor() {
        /** @Inject('UserModel')*/
        this.userModel;
    }

    //유저 정보 수정
    /** @Transactional */
    updateUser(id, name, age) {
        try {
            this.userModel.update(
                {
                    name: name,
                    age: age
                },
                {
                    where: {id: id}
                }
            );

            return await this.userModel.findByPk(id);
        } catch (e) {
            console.error(e);
        }
    }
}

Controller
src/backend/user/controller/UserController.js

/** @Controller*/
/** @RequestMapping ('/users') */
export class UserController {
    constructor() {
        /** @Inject('UserService')*/
        this.userService;
    }

    //유저 정보 수정
    /** @RequestMapping('/:userId', put) */
    updateUser(req, res){
        const userId = req.params.userId;
        const name = req.body.name;
        const age = req.body.age * 1;
        const user = this.userService.updateUser(userId, name, age);

        res.send(user);
    }
}

🧵 유저 삭제하기 - Delete

Service
src/backend/user/service/UserService.js

/** @Service */
export class UserService {
    constructor() {
        /** @Inject('UserModel')*/
        this.userModel;
    }

    //유저 삭제
    /** @Transactional */
    deleteUser(id){
        try{
            this.userModel.destroy({
                where : {id : id}
            });

            return this.userModel.findAll();
        }catch (e) {
            console.error(e);
        }
    }
}

Controller
src/backend/user/controller/UserController.js

/** @Controller*/
/** @RequestMapping ('/users') */
export class UserController {
    constructor() {
        /** @Inject('UserService')*/
        this.userService;
    }

    //유저 삭제
    /** @RequestMapping('/:userId', delete)*/
    deleteUser(req, res){
        const userId = req.params.userId;
        const list = this.userService.deleteUser(userId);

        res.send(list);
    }
}

🎨 Service, Controller에 사용된 어노테이션 설명

Service

  • Service는 실제 비즈니스 로직을 작성하는 파일입니다. Service 파일이라는 것을 명시하기 위해 @Service 어노테이션을 class 상단에 작성합니다. 반드시 /** */ 주석 안에 작성합니다.
  • Sequelize를 통해 DB 작업을 수행하기 위해 Model 파일을 사용합니다. 정의한 UserModel 파일을 가져오기 위해 @Inject 어노테이션을 사용합니다.
  • DB 작업 수행 중 예기치 못한 에러가 날 경우 수행한 작업을 되돌리기 위해 @Transactional 어노테이션을 사용합니다.

Controller

  • Controller는 API를 요청할 경로를 정의하고 request나 response와 관련된 작업을 수행합니다. Controller 파일을 명시하기 위해 @Controller 어노테이션을 class 상단에 작성합니다. 반드시 /** */ 주석 안에 작성합니다.
  • 유저 CRUD 기능을 구현할 때 공통적으로 들어가는 API 경로는 /users입니다. 따라서 공통적으로 사용하는 경로를 class 상단에 @RequestMapping 어노테이션을 사용합니다.
  • Controller에서는 Service 파일을 사용하여 해당 API에서 필요한 작업을 수행합니다. 따라서 @Inject 어노테이션을 사용해 UserService 파일을 가져옵니다.



✨ 전체 코드

Service

/** @Service */
export class UserService {
    constructor() {
        /** @Inject('UserModel')*/
        this.userModel;
    }

    //유저 생성
    /** @Transactional */
    createUser(name, age) {
        try {
            const user = this.userModel.create({
                name: name,
                age: age
            });
            return user;
        } catch (e) {
            console.error(e);
        }
    }

    //유저 목록 조회
    /** @Transactional */
    getUsers() {
        try {
            return this.userModel.findAll();
        } catch (e) {
            console.error(e);
        }
    }

    //유저 상세 조회
    /** @Transactional */
    getUserById(id) {
        try {
            return this.userModel.findByPk(id);
        } catch (e) {
            console.error(e);
        }
    }

    //유저 정보 수정
    /** @Transactional */
    updateUser(id, name, age) {
        try {
            await this.userModel.update(
                {
                    name: name,
                    age: age
                },
                {
                    where: {id: id}
                }
            );

            return this.userModel.findByPk(id);
        } catch (e) {
            console.error(e);
        }
    }

    //유저 삭제
    /** @Transactional */
    deleteUser(id){
        try{
            this.userModel.destroy({
                where : {id : id}
            });

            return this.userModel.findAll();
        }catch (e) {
            console.error(e);
        }
    }
}

Controller

/** @Controller*/
/** @RequestMapping ('/users') */
export class UserController {
    constructor() {
        /** @Inject('UserService')*/
        this.userService;
    }

    //유저 생성
    /** @RequestMapping('/', post) */
    createUser(req, res) {
        const name = req.body.name;
        const age = req.body.age * 1;
        const user = this.userService.createUser(name, age);
        res.send(user);
    }

    //유저 목록 조회
    /** @RequestMapping('/', get)*/
    findAllUser(req, res){
        const list = this.userService.getUsers();
        res.send(list);
    }

    //유저 상세 조회
    /** @RequestMapping('/:userId', get) */
    findUser(req, res){
        const userId = req.params.userId * 1;
        const user = this.userService.getUserById(userId);

        res.send(user);
    }

    //유저 정보 수정
    /** @RequestMapping('/:userId', put) */
    updateUser(req, res){
        const userId = req.params.userId;
        const name = req.body.name;
        const age = req.body.age * 1;
        const user = this.userService.updateUser(userId, name, age);

        res.send(user);
    }

    //유저 삭제
    /** @RequestMapping('/:userId', delete)*/
    deleteUser(req, res){
        const userId = req.params.userId * 1;
        const list = this.userService.deleteUser(userId);

        res.send(list);
    }
}
profile
헐 제가 회사를 다니면서 개발을 하고 있어요 이게 무슨 일이죠?

0개의 댓글