API 활용하기

dongmin·2023년 11월 15일
0
post-thumbnail

API?

Application Programming Interface의 약자로 웹 개발 과정에서 웹과 다른 시스템간에 서로 데이터를 주고받을 수 있는 방법을 제공한다.

예를 들어 api는 서버의 데이터나 외부 데이터를 활용할 수 있게 한다.

웹 개발자에게 있어서 Back-end와 Front-end가 소통하는 매개체인 것이다.

API 명세서


API는 위와 같이 명세서가 존재한다.

이는 API를 사용하는 개발자에게 필요한 정보를 제공한다.

API 사용법

GET


1번째 항목인 getTodos에 대한 상세정보이다. URL과 요청 메서드가 작성되어 있고 데이터가 어떻게 담겨있는지 보여준다.

이 명세서를 보고 다음과 같이 코드를 작성하여 데이터를 얻을 수 있다.

  const getTodos = async () => {
    const response = await axios.get("/api/todos");
  };

axios 라이브러리를 활용하여 HTTP 요청을 하는데 명세서에 쓰여진대로 HTTP GET을 /api/todos 주소로 요청한다.

그러면 response에는 명세서에 작성되어 있는 응답 데이터가 들어오게된다.

응답 데이터에 접근하고 싶다면 response.data로 접근할 수 있다.

_async 함수는 Promise를 반환하는데 await 은 Promise를 처리할 때까지 함수를 중단시킨다. 따라서 axios.get 요청을 하고 응답이 완료될 때까지 코드 실행을 일시 중지시킨다.

이렇게 되면 코드가 동기식으로 실행되서 코드의 가독성이 좋아진다._

POST


2번째 항목인 createTodo에 대한 상세정보이다. 이번엔 POST 요청이다.

POST 요청은 HTTP body에 데이터를 담아 서버로 전송한다.

const createTodo = async () => {
  
  const formData = new FormData();
  
  formData.append("todoData", input);
  formData.append("file", imageFile);
  
  const response = await axios.post("api/todos",formData,{
    headers: {
                "Content-Type": "multipart/form-data",
            },
    );
}

GET 요청 할때와 달라진 것은 보낼 데이터를 저장하고 post의 두 번째 인자로 넣어주고 3번째 인자에서 2번째 인자에서 보낼 데이터가 어떤 타입인지 알려주는 Content-Type 설정을 해준다는 것이다.

필요한 정보가 모두 명세서에 적혀있으니 명세서대로 작성해주면 된다.

만약 응답 데이터의 id값에 접근하고 싶다면 response.data.id로 접근하면 된다.

PUT


이번엔 PUT 요청이다. PUT 요청은 데이터의 정보를 수정할 때 사용하기 때문에 Update기능을 구현하는데 유용하다.

const updateTodo = async (id) => {
    const response = await axios.put(`/api/todos/${id}`, 대체할 데이터 );
  };

요청 URL에 id가 들어가야 하므로 id값을 매개변수로 받아와서 put 요청을한다.

axios.put 의 두 번째 인자로 대체할 데이터가 들어간다.

그러면 response에 대체된 데이터가 들어가게 되어서 response.data로 대체된 데이터에 접근할 수 있다.

DELETE


마지막으로 DELETE 요청이다.

const deleteTodo = async (id) => {
  await axios.delete(`api/todos/${id}`);
}

DELETE 요청을 따로 응답 데이터가 존재하지 않고 해당 데이터가 서버에서 삭제된다.

API 활용하기

지금까지 API를 사용하는 방법에 대해서 알아보았다.

이제 API를 활용하여 TodoList를 구현해보도록 하겠다.

TodoList 데이터 생성하기

먼저 사용자에게 데이터를 입력받도록 하기 위해서 다음과 같이 form태그를 작성한다.

            <form onSubmit={createTodo}>
                <input
                type="text"
                value={input}
                placeholder="할 일을 등록해보세요"
                onChange={(e)=> setInput(e.currentTarget.value)}/>
                <input
                type="file"
                ref={inputRef}
                onChange={onLoadFile}/>
                <button onClick={createTodo}></button>
            </form>

이렇게 작성하면 사용자로부터 text와 file을 입력받을 수 있다.

사용자가 text와 file을 입력하고 버튼을 클릭할 때 createTodo함수를 실행 시키는 것이다.

	const inputRef = useRef();
	const [todo,setTodos] = useState([]);
	const [input, setInput] = useState("");
	const [imageFile, setImageFile] = useState();

    const  createTodo = async (e) => {
        e.preventDefault();

        if(input == "") return;	//입력 값이 없으면 리턴

        const formData = new FormData();
        formData.append("todoData",input);	//todoData의 값을 input
        formData.append("file",imageFile);  //file의 값을 imageFile

        const response = await axios.post("api/todos", formData, {
            headers: {
                "Content-Type": "multipart/form-data",
            },
        });
		//todos의 이전상태의 값에 현재상태의 값을 추가함
        setTodos((prev)=>[...prev,response.data]);
      	//text입력창을 비워줌
        setInput("");
      	//form요소의 값 초기화
        inrputRef.current.value = null;
    };

여기까지 작성하면 할 일을 입력했을 때 사용자가 입력한 데이터가 response.data에 추가된다.

TodoList 생성한 데이터 보여주기

우선 사용자가 데이터를 볼수 있도록 다음과 같이 작성한다.

<ul>
	{todos.map((todo)=>(	//todos 배열의 각 요소에 대해 모두 실행
	<li key={todo.id}>		//todo는 각 요소를 나타냄
    //사용자가 입력한 파일은 thumbnail에 링크가 담아져 있으므로 다음과 같이 출력
	{todo.thumbnail && (
	<img className="thumbnail" src={todo.thumbnail} alt="thumbnail" />)}
	<span>{todo.title}</span>	//각 요소의 title값을 보여줌
	</li>))}
</ul>

사용자에게 TodoList를 보여주는 과정은 저장되어 있는 데이터를 가져오기만 하면되는 것이다.

여기에서 사용자가 입력하는 즉시 데이터는 추가되지만 추가된 데이터를 사용자에게 보여주기 위해서는 다시 렌더링해 주어야 한다.

useEffect문을 사용하여 getTodo가 실행될 때마다 다시 렌더링하도록 하여 사용자가 입력할 때마다 즉시 확인할 수 있도록 한다.

useEffect(() => { getTodos() },[]);	//getTodos 호출시 렌더링

TodoList 삭제하기

위의 코드에서 삭제 버튼을 생성하는 코드 한 줄만 추가해주도록 한다.

<ul>
	{todos.map((todo)=>(	
	<li key={todo.id}>		
	{todo.thumbnail && (
	<img className="thumbnail" src={todo.thumbnail} alt="thumbnail" />)}
	<span>{todo.title}</span>
	</li>))}
</ul>
//추가된 코드 클릭 시 deleteTodo실행
<button onClick={()=>{deleteTodo(todo.id)}}/> 

deleteTodo 함수도 추가적인 작업이 필요하다.

const deleteTodo = async (id) => {
    await axios.delete(`/api/todos/${id}`);
  	//추가된 코드
    const filteredTodos = todos.filter((todo) => todo.id !== id);
    setTodos(filteredTodos);
  };

이 함수에서는 delete요청으로 특정 id에 해당하는 데이터를 삭제한다.

todos.filter()는 todos의 모든 요소들에 대해서 삭제된 id에 대한 요소를 제외한 모든 배열 요소들을 filteredTodos에 저장한다.

setTodos(filteredTOdos); 에서 필터링 된 배열이 todos의 값이 된다.

deleteTodo()를 실행하는 버튼을 클릭하면 todos의 값이 필터링된 배열 값으로 바뀌게 되어 TodoList에서 해당 id값의 리스트가 삭제된다.

TodoList 업데이트하기

여기서 말하는 update란 PUT 요청을 통해서 데이터를 수정하는 것을 뜻한다.

응답 데이터 안에 "done" 항목이 있는데 이 값을 수정하도록 할 것이다.

<ul>
	{todos.map((todo)=>(	
	<li key={todo.id}>
      //추가한 코드
     <input	type="checkbox"
            checked={todo.done}
            onChange={() => updateTodo(todo.id)}/>
     // 
      
	{todo.thumbnail && (
	<img className="thumbnail" src={todo.thumbnail} alt="thumbnail" />)}
	<span>{todo.title}</span>
	</li>))}
</ul>
<button onClick={()=>{deleteTodo(todo.id)}}/> 

사용자가 할 일을 하게되면 체크박스에 체크를 하고 todo.done값이 true, 체크를 해제하게 되면 false값이 들어가고 updateTodo 함수를 호출하게 된다.

updateTodo 함수도 추가적인 작업이 필요하다.

  const updateTodo = async (id) => {
    const response = await axios.put(`/api/todos/${id}`);
    
    //추가한 코드
    const updateTodos = todos.map((todo) =>
      todo.id === id ? response.data : todo
    );
    setTodos(updateTodos);
    //
  };

updateTodos에는 todos의 모든 요소들에 대해서 response.data를 받아와서 todo.done값이 수정된 데이터가 들어가게 된다.

setTodos(updateTodos);를 통해서 todos의 값이 업데이트된다.

지금까지 API에 대해서 알아보고 활용하여 TodoList의 기능을 구현해보는 과정을 통해서 API를 사용하는 이유와 어떻게 사용해야하는지 언제 사용해야하는지 이해할수 있게 되었다.

API 출처

profile
아이스박스

0개의 댓글