본문 바로가기
TIL

[231005] Rest API, JSON 공부, 페이지 기능 구현

by 진진리 2023. 10. 5.
728x90
  • 메인 페이지 & 나의 개인 페이지 완성

 

- 현재 메인 페이지 작성 완료하신 분까지만 버튼 기능 + 검색 기능으로 페이지 이동

<script type="module">
...
async function getSearchResult() { // 검색 결과 보여주는 함수
            searchWord = $('#search').val();

            if (searchWord == '김성훈')
                location.href = '1.html'; // 김성훈님
            else if (searchWord == '김민선')
                location.href = '2.html'; // 김민선님
            else if (searchWord == '유민아')
                location.href = 'minahpage.html'; // 유민아님
            else if (searchWord == '이예진')
                location.href = 'yejinpage.html'; // 이예진님
            else
                alert(`${searchWord} 에 대한 검색 결과를 찾을 수 없습니다.`);
            } 

        let searchWord = '';
        $('#search').keydown(function (e) { // enter 눌렀을 때 검색어 가져와서 전달
            if (e.keyCode == 13) {
                e.preventDefault();
                getSearchResult();
            }
        })

        $('#index').click(function(){
            location.href =  'index.html';
        })

        $('#minah').click(function () {
            location.href = 'minahpage.html';
        })

        $('#yejin').click(function(){
            location.href =  'yejinpage.html';
        })

    </script>

 


Rest API 알아보기

  • REST란?
    • Representational State Transfer의 약자로 자원을 이름으로 구분하여 해당 자원의 상태를 주고 받는 모든 것.
    • 자원의 상태: JSON 혹은 XML을 통해 데이터를 주고 받는 것이 일반적
    • HTTP URI를 통해 자원을 명시하고 HTTP Method(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 의미

 

  • CRUD OperatioN
    • Create: 생성(POST)
    • Read: 조회(GET)
    • Update: 수정(PUT)
    • Delete: 삭제(DELETE)
    • HEAD: header 정보 조회(HEAD)

 

  • REST 구성 요소
    1. 자원: URI
      • 모든 자원의 고유한 ID(URI)는 Server에 존재
      • Client는 URI를 이용해 자원을 지정하고 해당 자원에 대한 상태 조작을 Server에 요청
    2. 행위: HTTP Method
      • GET, POST, PUT, DELETE와 같은 메서드 제공
    3. 표현(Representation)
      • Client가 자원의 상태에 대한 조작을 요청하면 Server는 이에 적절한 응답(Representation)을 보냄
      • 하나의 자원은 JSON, XML, TEXT, RSS 등 여러 형태로 나타내어 질 수 있음
      • JSON 혹은 XML을 통해 데이터를 주고 받는 것이 일반적

 

  • REST API란?
    • API: 데이터와 기능의 집합을 제공하여 컴퓨터 프로그램간 상호작용을 추진, 서로 정보를 교환 가능하도록 하는 것
    • REST API: REST를 기반으로 서비스 API를 구현한 것

 

  • RESTful: REST API를 제공하는 웹 서비스를 나타내는 용어

 


JSON 알아보기

  • JSON: Javascript 객체 문법으로 구조화된 데이터를 표현하기 위한 문자 기반의 표준 포맷
    • 기본 형태: { key : value }
    • { key1 : { intKey : inValue }, key2 : [arr1, arr2, arr3] }: 객체는 중괄호({}), 배열은 대괄호([])
    • 타입: 숫자, 문자열, 불리언, 객체, 배열, null
var Characters = []

var Character = {
    '이름' : '유명한',
    '성별' : '남',
    '나이' : '38'
}

Characters.push(Character); //데이터를 추가

//항목 추가
Character["성인여부"] = true;

//항목 삭제
delete Character.성인여부

  • Rest API 명세서 작성
기능 Method URL request response
메인 페이지 내 방명록 최신글 GET /logs - {
 content: '안녕하세요'
 date: '2023-10-05'
}
달성도 상태바 반영 GET /goals - {
achievement: true,
count: 4,
main: true,
personal: true,
visitorBook: false,
}
달성도 상태바 수정 POST /goals {
achievement: true,
count: 4,
main: true,
personal: true,
visitorBook: false
}
{
achievement: true,
count: 4,
main: true,
personal: true,
visitorBook: false,
}
방명록 글 생성 POST /logs {
 content: '안녕하세요'
 date: '2023-10-05'
 name: '홍길동'
 pw: '1234'
}
-
방명록 글 삭제 DELETE /logs - -

  • 달성도 진행상태바 구현

db를 사용하지 않고 페이지 내에서 체크박스 개수를 진행상태바에 반영하는 것은 간단했으나

db를 이용하는 과정에서 막힘

1. addDoc에서 firebase에 시간 순서대로 데이터가 저장되는 것이 아니기 때문에 getDocs를 가져오는 것이 어려움

2. getDocs 후 forEach문을 통해서 데이터를 가져오는데 가장 최근의 데이터 하나만 가져오고 싶을 때 어떻게 해야할지 모름

-> 팀원이 구현한 내용

...
import { doc, collection, addDoc, updateDoc } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
import { getDocs, query, where } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
...
async function dataUpdate() {
            let boxes = $("input[type='checkbox']:checked");
            let checked = boxes.length;

            let getId = $('#sendbtn').on('click', '.checkbox', function () {
                let boxId = $(this).attr('id');
            })

            let update = { // 업데이트할 데이터
                'main': $(`#main`).is(':checked'),
                'personal': $('#personal').is(':checked'),
                'search': $(`#search-input`).is(':checked'),
                'achievement': $(`#achievement`).is(':checked'),
                'visitorBook': $(`#visitorBook`).is(':checked'),

                'count': checked
            };

            let dataPackage = await getDocs(collection(db, "goals"));
            dataPackage.forEach(async (data) => {
                await updateDoc(doc(db, "goals", data.id), update);
                window.location.reload(); //반복문 안에 넣음으로써 새로고침이 비동기적으로 호출되지 않도록 함
            })
        }

        $('#sendbtn').click(async function () {
            dataUpdate();
        });


        $(document).ready(async function () {
            let getData = await getDocs(collection(db, "goals"));
            let temp;
            getData.forEach((doc) => {
                console.log("Current data: ", doc.data());
                let goal = doc.data();

                let main = goal['main'];
                let personal = goal['personal'];
                let searchInput = goal['search'];
                let achievement = goal['achievement'];
                let visitorBook = goal['visitorBook'];

                let count = goal['count'];



                $('#main').prop("checked", main);
                $('#personal').prop("checked", personal);
                $('#search-input').prop("checked", searchInput);
                $('#achievement').prop("checked", achievement);
                $('#visitorBook').prop("checked", visitorBook);

                progressbar.style.width = ((count / 5) * 100) + "%";
            });

        })

 

- 어떤 체크 박스가 체크되었는지 저장 후 체크 상태도 유지함

- 데이터를 add하는 것이 아니라 getDocs로 가져와서 각 필드의 요소를 update함

- dataUpdate() 함수는 버튼이 클릭될 때, 페이지가 로드될 때 작동해야 하므로 따로 함수를 작성

 

*updateDoc을 위해 import할 라이브러리도 몰랐기에 추가