ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 3차 프로젝트 회고
    코린이 일기/3차 프로젝트 2023. 11. 5. 22:00
    728x90

     

    뿌듯하면서도 많은 교훈을 얻은
    3차 프로젝트 회고

     

        목차

    1. 프로젝트 정의
    2. 프로젝트 목표
    3. 프로젝트 과정
    4. 프로젝트 내용
    5. 코드 문제 & 해결
    6. 기억에 남는 코드

    7. 느낀 점 

     

     

    1.  프로젝트 정의

    • React와 Node.js를 활용하여 3주 동안 웹 서비스의 다채로운 특징을 가진 새로운 기능을 담아낼 수 있는 사이트 구축
    • AWS EC2를 이용하여 백엔드 서버 구축, S3를 이용하여 사진 데이터 처리
    • 온라인 또는 오프라인으로 팀원들과 소통하며 PET의 관점으로 웹 페이지를 분석
    • 위치 기반 지역 마켓 플레이스 핵심 기능과 제품, 대상을 선정하여 어떠한 도메인으로 프로젝트를 진행 할 지 결정 

     

    2.  프로젝트 목표

    • 위치 기반 지역 마켓 플레이스에 대한 특징으로 다양한 기능 개발(회원가입 기능, 로그인 기능, 장바구니 기능, 위치 기반 서비스 등)
    • 프론트엔드는 회원가입 페이지, 로그인 페이지, 장바구니 페이지, 제품 상세페이지를 개발
    • 백엔드는 회원가입 API, 로그인 API, 제품 상세 API, 장바구니 API, 외부결제 API, 위치 기반 API 를 개발
    • 프론트엔드에서 개발한 페이지와 백엔드 API를 통신하여 프로젝트를 완성
    • 프로젝트 회고 미팅을 진행하여 프로젝트 기간에 느꼈던 점을 기록

     

    3.  프로젝트 과정

    프론트엔드 2명 & 백엔드 5명으로 한 팀이 구성되어 매일 진행 상황을 공유하였다.

    • 매일 진행되는 Stand-up Meeting
    • Slack을 통한 소통
    • Notion 과 Trello를 통한 일정 관리
    • Github를 통한 코드 공유
    • 웹 페이지 PET 분석
    • 위치 기반 지역 마켓 플레이스 주제 선정
    • 프로젝트 기초 ERD 작성
    • 프로젝트 초기세팅 
    • 회원가입,로그인,장바구니,메인,제품상세,찜,외부결제,위치기반 API 구성

     

    4.  프로젝트 내용

    프로젝트 시작 첫날, 팀원들과 함께 주제 선정에 대한 의견을 나누었다. 지난 1차와 2차 프로젝트를 통해 의사소통 스킬과 의견을 조율하고 전달하는 데에 좀 더 능숙해졌다고 느껴질 만큼 활발하게 소통하였다. 주제로는 가족 가계부 플랫폼, 온라인 건강 피트니스 플랫폼, 위치 기반 지역 마켓 플레이스, 온라인 이벤트 티켓팅 플랫폼 등 4가지 옵션이 있었고, 토론을 통해 위치 기반 지역 마켓 플레이스가 가장 적합한 주제로 결정되었다. 선택한 이유는 여러 서비스에서 확인할 수 있는 위치 기반 거래의 활발성과 플랫폼들의 다양성 때문이다. 특히 위치 기반 서비스 구현과 더불어 외부 결제 API 및 소셜 로그인을 구현하며 다양한 경험을 쌓고 싶었던 생각이 큰 비율을 차지했다.

     

    1) PET분석 

    • 회원 : 어떠한 고객이 우리 서비스의 회원층이 될 수 있는가? / 고객들을 어떻게 유입시킬 수 있는가? / 어느 정보까지 필요한가?
    • 서비스 :  우리 서비스는 어떻게 정의할 수 있는가?
    • 매출 : 우리 서비스의 매출은 어떻게 이루어지는가?
    • 리포팅 : 분석 자료를 어떻게 화면으로 보여야 하는가?
    • 데이터보안 : 어떻게 보안 관리를 할 수 있는가?

     

    우리는 주로 서비스 영역에 중점을 두었다. 지역 커뮤니티를 강화하고자 하는 취지로, 구매 및 판매가 모두 가능한 서비스를 강조하였다. 특히 매출 부분에서는 프리미엄 서비스(구독)를 이용하는 사용자들에게 다양한 혜택을 부여하는 방향으로 기획하였다. 이러한 혜택에 대한 구체적인 내용은 아래와 같다.

     

    • 구매자가 프리미엄 서비스 구독 시 배송료 무료 혜택
    • 배너 광고 제공을 통한 광고 수익 창출
    • 판매자 수익에 따른 결제 수수료
    • 프리미엄 판매자의 상위 노출

     

    2) 기획

    유저셀러로 나뉜다.
    누구나 판매자가 될 수 있다.
    프리미엄 구독 서비스를 제공한다.
    지역사회 거래 및 커뮤니티 발전에 기여한다.
    위치 기반을 통하여 지정된 장소에서 픽업을 하거나 배송을 받을 수 있다.
    어드민 페이지 내의 리포팅으로 주문내역, 주문상태와 기간별 데이터를 노출 시킨다.
    AWS 보안 설정과 토큰을 이용하여 보안 관리를 한다.

     

     

    3) ERD 작성

    그림 1. 초기 ERD 작성

     

     

    ERD를 구성하면서 주 사용자인 유저와 셀러 중심으로 세분화하며 총 14개의 테이블을 구성했다.

     

    • 유저(users) 테이블 : 회원 정보를 저장하는 테이블
    • 셀러(sellers) 테이블 : 셀러 정보를 저장하는 테이블
    • 제품(products) 테이블 : 판매되는 제품의 정보를 저장하는 테이블
    • 제품 카테고리(product_categories) 테이블 : 제품을 카테고리로 분류하는 테이블
    • 제품 메인 이미지(product_main_images) 테이블 : 제품의 메인 이미지 정보를 저장하는 테이블
    • 제품 상세 이미지(product_detail_images) 테이블 : 제품의 상세 이미지 정보를 저장하는 테이블
    • 장바구니(carts) 테이블 : 유저가 선택한 제품을 담아두는 테이블
    • 주문(orders) 테이블 : 주문 정보를 저장하는 테이블
    • 주문 상세(order_details) 테이블 : 주문된 제품의 상세 정보를 저장하는 테이블
    • 좋아요(likes) 테이블 : 사용자가 '좋아요' 를 누른 제품에 대한 정보를 저장하는 테이블
    • 결제(payments) 테이블 : 결제 정보를 저장하는 테이블
    • 리뷰(reviews) 테이블 : 제품에 대한 리뷰 정보를 저장하는 테이블
    • 유저 프리미엄(user_premium) 테이블 : 프리미엄 구독 서비스를 신청한 유저에대한 정보를 저장하는 테이블
    • 셀러 프리미엄(seller_premium) 테이블 : 프리미엄 구독 서비스를 신청한 셀러에대한 정보를 저장하는 테이블

     

    프로젝트 진행 중에는 효율성과 상세한 구성에 대해 고민하며 다수의 수정을 했고 수정한 내용은 아래와 같다.

     

    • seller 테이블 user_id FK 삭제 : 유저 테이블에 seller_id 를 추가하기 위한 삭제
     
    ALTER TABLE `sellers` DROP FOREIGN KEY `sellers_ibfk_1`;
     
    ALTER TABLE sellers DROP COLUMN user_id;
     

     

    • user 테이블 seller_id FK 추가 : 기본적으로 유저로 가입 후 셀러 등록 진행이 가능하여 추가
     
    ALTER TABLE users ADD seller_id INT NULL;
     
    ALTER TABLE `users` ADD FOREIGN KEY (`seller_id`) REFERENCES `sellers` (`id`) ON DELETE CASCADE;
     

     

    • user 테이블 컬럼 5가지 NOT NULL -> NULL 로 변경 :  기본 회원가입 페이지가 아닌 추가 정보 입력페이지에 들어가는 내용이므로 입력하지 않아도 되기 때문에 변경
     
    ALTER TABLE users MODIFY COLUMN `phone_number` VARCHAR(255) NULL;
     
    ALTER TABLE users MODIFY COLUMN `zip_code` VARCHAR(255) NULL;
     
    ALTER TABLE users MODIFY COLUMN `address` VARCHAR(255) NULL;
     
    ALTER TABLE users MODIFY COLUMN `address_details` VARCHAR(255) NULL;
     
    ALTER TABLE users MODIFY COLUMN `password` VARCHAR(255) NULL;
     

     

    • product_detail_images 테이블 comments 컬럼 추가 : 제품 상세 이미지에 대한 내용 작성을 위한 컬럼 추가
     
    ALTER TABLE product_detail_images ADD COLUMN `comments` VARCHAR(1000) NOT NULL;
     

     

    • carts 테이블 status 컬럼 추가 : 장바구니 내 제품 결제 여부 확인(단순히 장바구니에 담아두는 경우를 디폴트로 설정)
     
    ALTER TABLE `carts` ADD COLUMN `status` INT NOT NULL DEFAULT 0;
     

     

    • users 테이블 points 컬럼 추가 : 포인트 컬럼 누락으로 추가
     
    ALTER TABLE `carts` ADD COLUMN `status` INT NOT NULL DEFAULT 0;
     

     

    • users 테이블 latitude(위도),longtitude(경도) 컬럼 추가 :  위치 기반 서비스를 위한 위도,경도 추가
     
    ALTER TABLE users ADD COLUMN latitude DOUBLE;

    ALTER TABLE users ADD COLUMN longitude DOUBLE;
     

     

    • sellers 테이블 latitude(위도),longtitude(경도) 컬럼 추가 :  위치 기반 서비스를 위한 위도,경도 추가
     
    ALTER TABLE sellers ADD COLUMN latitude DOUBLE;

    ALTER TABLE sellers ADD COLUMN longitude DOUBLE;
     

     

     

     

    그림 2. DBeaver로 생성한 최종 ERD

     

    프로젝트 이후 최종 수정된 ERD를 DBeaver를 사용하여 직접 다이어그램을 작성했다. 추가적으로 데이터베이스 테이블 간의 관계와 속성들이 명확하게 드러나도록 재배치하였다. 아울러 프로젝트 이후 ERD 작성에 대하여 얻은 세 가지 깨달음을 정리해보았다.

     

    • 이해하기 쉽도록 구성하기 : 다른 개발자나 팀원들이 봤을 때, 데이터베이스 구조에 대한 이해가 높아지면 협업과 유지보수가 원활해질 수 있으므로 컬럼, 속성, 테이블 배치 등을 신경 써서 명확하고 직관적으로 구성한다.
    • 테이블 간 관계 설정 주의하기 : 외래키(FK) 설정을 통하여 데이터베이스의 무결성 보장과 함께 효율적인 쿼리 작성이 가능해진다. 따라서 1:1, N:1, N:N 관계를 명확히 구분하여 데이터의 일관성과 정확성을 지키도록 한다.
    • 효율적인 구성 고려하기: 필요한 속성을 정확히 식별하여 입력해 준다. 불필요한 정보는 피하고, 간결하게 구성한다. 다양한 참고 자료를 활용하여 효율적인 구조를 찾아보고, 데이터의 특성에 맞게 최적화된 스키마를 구축한다.

     

    4) User Flow Chart

    그림 3. User Flow Chart 작성

     

    이러한 User Flow Chart를 통해 사용자 경험을 파악하고, 각 단계에서의 흐름을 명확하게 이해할 수 있도록 구성했다.

     

    • 회원가입 흐름 : 사용자가 웹사이트에 접속 후 회원가입 버튼 클릭하게 되면 카카오 소셜 로그인 절차를 통하여 가입이 완료됨 이메일,휴대폰,비밀번호 필수 정보 통하여 절차 진행
    • 로그인 흐름 : 사용자가 입력한 이메일(ID)과 비밀번호 유효성 검사를 통하여 로그인이 진행되며 성공 후 메인 페이지로 이동
    • 구독 흐름 : 마이페이지에서 구독 버튼을 클릭하여 요금제를 선택하고 결제 절차를 진행
    • 장바구니 흐름 : 메인 페이지의 제품 중 장바구니에 담을 제품을 선택하거나 제품을 클릭하여 상세 페이지에서 수량을 선택 후 장바구니에 담을 수 있도록 진행
    • 결제 흐름 : 장바구니로 이동하여 결제하려는 제품을 선택 후 결제 페이지로 이동하여 배송 방법(직접 수령,택배 수령)과 선택한 결제 수단(포인트,카카오페이)에 따라 결제 절차가 진행

     

    5) 초기세팅

     

    프로젝트 초기 설정을 진행하는 단계에서 팀 내 소통에 일부 어려움이 있었다. 초기에는 해당 작업을 맡아 진행할 예정이었으나, 다른 팀원이 이를 맡아 진행하겠다는 의사를 밝혔고, 협업과 원활한 팀 분위기를 위해 양보하였다. 그러나 예상치 못한 이유로 초기 설정에 필요한 여러 패키지가 누락되었고, 환경변수 설정도 제대로 이루어지지 않아 서버 구동에 오류가 발생했다. 원활한 프로젝트 진행을 위해 신속한 조치가 필요했기 때문에 해당 이슈를 해결하기 위해 다시 한번 초기 세팅을 담당하였다. 추가로 필요한 패키지와 버전을 파악하고 환경변수 설정을 수정하여 작업을 마무리할 수 있었다. 이러한 어려움을 극복하며 프로젝트에 보다 나은 환경을 제공할 수 있도록 최선을 다했다. 초기 세팅에 사용된 패키지는 아래와 같다.

     

    • dependency :  express, mysql, typeorm, cors, bcrypt, jwt, dotenv
    • devDependency : nodemon, morgan 

     

    6) 티켓분배 

    프로젝트 내용을 구체적으로 세분화하여 티켓으로 나누었고, 이를 크게 총 6가지로 구분하였다.

    • 회원가입 / 로그인
    • 제품 
    • 장바구니
    • 주문 및 결제
    • 리뷰
    • 위치기반

    이 중에서 나에게 할당된 티켓은 총 4가지로 구분 되었다.

    • 제품 상세 페이지
    • 리뷰 작성
    • 리뷰 수정
    • 외부결제(PortOne)

     

    5.  코드 문제 & 해결

     

      1) 제품 상세 페이지 로우쿼리 작성

    그림 4. 제품 상세 쿼리문

     

    부트캠프 동안 가장 인상적이었던 순간은 이번 3차 프로젝트에서 작성한 쿼리문 경험이었다. 처음으로 사이트의 메인 기능을 담당하는 제품 정보를 가져오는 쿼리문을 작성했는데, 이전 프로젝트에서 아이디, 이름, 이메일, 전화번호와 같은 몇 가지 정보를 불러오는 쿼리문과는 달리, 제품 정보는 다양하고 복잡한 구조를 가지고 있었고 많은 생각과 수정이 필요한 작업이었다. 

     

     

    기존 쿼리문

    SELECT
        products.id AS productId,
        products.name AS productName,
        JSON_OBJECT('url', product_detail_images.url, 'comments', product_detail_images.comments) 
        AS productDetailImages,
        products.images AS productImg,
        products.price AS originalPrice,
        products.discount_rate AS discountRate,
        (products.price * products.discount_rate)/100 AS discountAmount,
        (products.price - (products.price * (products.discount_rate / 100))) AS totalPrice,
        COUNT(DISTINCT reviews.id) AS reviewNumbers,
        IFNULL(SUM(reviews.rating), 0) / NULLIF(COUNT(reviews.id), 0) AS rating,
        sellers.latitude AS latitude,
        sellers.longitude AS longitude
    FROM
        products
    LEFT JOIN
        reviews ON products.id = reviews.product_id
    INNER JOIN
        sellers ON products.seller_Id = sellers.id
    LEFT JOIN
        product_detail_images ON products.id = product_detail_images.product_id
    WHERE
        products.id = ${id}
    GROUP BY
        products.id, products.name, products.images, products.price, 
        products.discount_rate, sellers.latitude, sellers.longitude, 
        product_detail_images.url, product_detail_images.comments;

     

    수정된 쿼리문

    SELECT
        products.id AS productId,
        products.name AS productName,
        (SELECT JSON_ARRAYAGG(JSON_OBJECT
        ('url', product_detail_images.url,'comments', product_detail_images.comments))
         FROM product_detail_images
         WHERE products.id = product_detail_images.product_id
         GROUP BY product_detail_images.product_id) AS productDetailImages,
        products.images AS productImg,
        products.price AS originalPrice,
        products.discount_rate AS discountRate,
        (products.price * products.discount_rate)/100 AS discountAmount,
        (products.price - (products.price * (products.discount_rate / 100))) AS totalPrice,
        COUNT(DISTINCT reviews.id) AS reviewNumbers,
        IFNULL( IFNULL(SUM(reviews.rating), 0) / IFNULL(COUNT(reviews.id), 1),0) AS rating
        sellers.latitude AS latitude,
        sellers.longitude AS longitude
    FROM
        products
    LEFT JOIN
        reviews ON products.id = reviews.product_id
    INNER JOIN
        sellers ON products.seller_Id = sellers.id
    WHERE
        products.id = ${id}
    GROUP BY
        products.id;

     

     

    변경된 부분은 productDetailImages이다. 이미지와 코멘트가 하나가 아닌 여러 개일 수 있기 때문에, 동일한 값이 여러 번 반복해서 오는 것이 아니라 productId 하나에 대한 하위 정보로 올 수 있도록 해달라는 프론트 쪽의 요청으로 수정된 쿼리문 이었다.수정 전에는 필요한 데이터들이 나가기는 했지만 프론트 쪽에서 알아보기가 힘들었고, 백엔드 팀원들과의 소통에서도 쿼리문을 논리적으로 설명하기 어려운 부분이 있었기 때문에 이 과정에서 많은 고민을 했고 수정의 필요성을 느꼈다.

     

    이후 서브 쿼리를 사용하여 하나의 products에 여러가지 productDetailImages가 올 수 있음을 표현하였다.

    추가적으로 JSON_ARRAYAGG과 JSON_OBJECT를 이용하여 하나의 배열안에 여러 가지 객체가 들어갈 수 있도록 프론트에서 요구한 형식으로 정제하여 전달하였다.

     

    이후로 JSON 함수 2가지에 대하여 알게 된 계기가 되어 정리를 해보았다.

    • JSON_ARRAYAGG : 그룹화된 결과의 모든 값을 하나의 JSON 배열로 합쳐서 반환하며, 주로 관계형 데이터베이스에서 JSON 형식의 결과를 생성하고자 할 때 활용한다.
    • JSON_OBJECT주어진 키와 값 쌍으로 JSON 객체를 생성하며, 특정 컬럼의 값을 JSON 객체의 키와 값으로 변환할 때 사용된다. 주로 여러 컬럼의 값을 하나의 JSON 객체로 변환할 때 활용된다.

     

    그림 5. (좌) 기존 쿼리문의 결과 / (우) 수정된 쿼리문의 결과

     

     

    Postman을 사용하여 GET 요청을 보내 제품 상세에 대한 결과를 확인 하였다.

    배열인 productDetailImages 내에 여러 개의 url과 comments 묶음을 객체 형식으로 담아 전달할 수 있었다.

     

     

      2) 리뷰 작성 및 불러오기(Service)작성

    그림 6. reviewService 리뷰 불러오기 / 리뷰 작성하기

     

    reviewService에서는 리뷰 작성 및 불러오기에 대한 코드를 구현했다. 이를 위해, models 디렉토리에 위치한 모듈에서 reviewDao 객체를 가져와 사용하였다.

     

    리뷰 불러오기는 getReviews 함수를 이용하여 productId(제품ID)라는 매개변수를 받아 해당 제품의 리뷰를 조회하도록 작성하였다.

    reviewDao.getReviews는 리뷰 데이터베이스 관련 작업을 하는 getReviews 함수를 호출하고, 그 결과를 data 변수에 저장하도록 작성하였다.

     

    리뷰 작성하기는 createReviews 함수를 이용하여 userId, contents, images, productId, rating 라는 매개변수를 받도록 작성하였다.

    reviewDao.createReviews는 createReviews 함수를 호출하여, 그 결과를 data 변수에 저장하도록 작성 하였다.

     

     

      3) 리뷰 작성 및 불러오기(Model)작성

    그림 7. reviewDao 리뷰 불러오기 / 리뷰 생성하기

     

     

    reviewDao에서는 reviewService에서 호출한 함수들이 동작되도록 하는 쿼리문을 각각 작성하였다.

     

    리뷰 불러오기는 SELECT문을 사용하여 user의 review에 대한 정보들을 가져오도록 하고, users,reviews,products 테이블을 JOIN 하였다. 마지막으로 WHERE절의 ?와 [productId] 는 플레이스 홀더로 인젝션 공격에 대비하기 위하여 사용하였다.

     

    리뷰 작성하기INSERT문을 사용하여 reviews 테이블에 변수로 받아온 값들을 입력하였다. 마찬가지로 VALUES절 뒤의 ?와 []안의 변수들은 인젝션 공격에 대비하기 위하여 사용하였다.

     

    여기서 인젝션 공격과 플레이스 홀더에 대한 궁금점이 생겨 추가로 자세하게 알아보았다.

     

    • 인젝션(Injection) 공격주로 악의적인 사용자가 애플리케이션의 입력 폼 등을 통해 SQL 쿼리에 악성 SQL 코드를 주입하는 공격이다. 데이터베이스 시스템에 안전하지 않은 데이터가 전달되어 데이터베이스에 보안 문제를 일으킬 수 있다. 작성한 SQL 쿼리에 사용자로부터 입력받은 값을 직접 삽입하면, 악의적인 사용자가 입력값을 조작하여 의도치 않은 쿼리를 실행시키는 경우를 의미한다.
    • 플레이스 홀더(Placeholder) : SQL 문에서 동적으로 값을 삽입하는 데 사용된다. 사용자로부터 입력된 데이터를 SQL 쿼리에 직접 삽입하지 않고, 대신 특별한 표시자(? 또는 $1 등)를 사용하여 쿼리를 작성한다. 이렇게 하면 사용자로부터 입력된 값이 특수문자 혹은 SQL코드로 해석되는 것을 방지할 수 있으며 보다 안전한 쿼리 작성이 가능해진다. 대부분의 프로그래밍 언어와 데이터베이스 라이브러리에서는 플레이스 홀더를 지원하고 있다.

     

    6.  기억에 남는 코드

      1) 외부 결제(PortOne)

    const createPayment = async (imp_uid, userId) => {
      const getToken = await axios({
        url: 'https://api.iamport.kr/users/getToken',
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        data: {
          imp_key: process.env.IMP_KEY,
          imp_secret: process.env.IMP_SECRET,
        },
      });
    
      const { access_token } = getToken.data.response;
      if (!access_token) throwError(408, 'FAIL_TO_GET_TOKEN');
    
      const getPaymentInfo = await axios({
        url: `https://api.iamport.kr/payments/${imp_uid}`,
        method: 'GET',
        headers: { Authorization: access_token },
      });
    
      const { pg_provider, name, amount } = getPaymentInfo.data.response;
      if (!amount && !pg_provider && !name)
        throwError(400, 'FAIL_TO_GET_PAYMENT_RESPONSE');
    
      const shippingMethod = 'delivery';
    
      const result = await paymentDao.createPayment(
        pg_provider,
        amount,
        shippingMethod,
        userId
      );
      return result;
    };

     

    createPayment 함수안에 axios를 사용하여 POST 요청을 보내 사용자의 유효한 토큰을 발급한 뒤에 유효성 여부를 확인할 수 있게 한다. GET 요청을 통해서 tokenimp_uid를 전달하고 포트원에서는 사용자의 고유값한 값들을 받아 토큰과 함께 확인한다. 이렇게 결제 요청을 보낸뒤 결제 결과를 수신받는다. 이후에 결제사,이름,수량에 대한 내용을 paymentDao에 저장해준다.

     

    추가로 axios, accessToken, 외부 API 사용 방법에 대하여 간단히 정리해 보았다.

     

    • axios : Axios는 HTTP 클라이언트 라이브러리로, JavaScript 및 Node.js에서 사용할 수 있으며 주로 서버와의 HTTP 통신 및 API 요청에 활용된다. 사용하는 이유는 간편한 API, Promise 기반이라는 점 그리고 HTTP 요청 및 응답 변형에 능하다는 점이다.
    • accessToken 
      1. 인증 (Authentication): 사용자가 자신의 신원을 확인할 수 있도록 하고, 로그인한 사용자를 식별하고 보안을 강화할 수 있다.
      2. 권한(Authorization) : 특정 리소스 또는 기능에 대한 접근 권한을 부여한다. 서버는 accessToken을 통해 사용자의 권한을 확인하고, 이에 따라 허용된 작업을 수행하거나 거부할 수 있다.
    • 외부 API 사용 방법 : PortOne 과 같은 외부API의 사용 방법에 대해서 살펴보면 다음과 같다. 

    그림 8. PortOne 외부결제 과정

     

    7.  프로젝트를 마치며(느낀 점)

     

    부트캠프를 통해 1차, 2차, 3차 프로젝트까지 완료한 경험은 매우 소중하게 느껴졌다. 특히 3차 프로젝트에서는 다양한 경험을 통해 개발에 대한 깊은 이해와 학습을 얻을 수 있었다. 그중에서도 의사소통의 중요성을 강력하게 깨달았다. 팀원들과의 원활한 소통이 프로젝트의 효율성에 큰 영향을 미친다는 것을 몸소 체험하였고 말을 효과적으로 전달하는 방법에 대한 고민도 많이 했던 시간이었다. 나아가 현직에서는 팀원뿐만 아니라 다른 부서와의 협업에서도 말의 전달과 공유가 매우 중요할 것이기에 더욱이 신경 써야 할 부분이라고 마음속 깊이 새겨야겠다는 생각도 들었다. 마지막 프로젝트인 기업협업 인턴 기간에서도 배운 것들을 활용하고 나 자신에 대하여 발전할 수 있는 시간으로 활용할 것이다. 두려움과 설렘이 반반인데, 개발자로서 한발 더 나아갈 나를 응원하며 화이팅!

    728x90
Designed by Tistory.