til_230410

김강현·2023년 4월 10일
0

블체스-3기-TIL

목록 보기
7/12

Rest Api

REpresentational State Transfer
이렇게 쓰는 편 ( 자원의 이름과 전달 방식만으로 해당역할 추론 가능 )

  • 조회 : Get
  • 생성 : Post
  • 업데이트 : Put
  • 삭제 : Delete

REST API 특징

  • Server - Client 구조로 되어 있습니다.
  • 자윈을 가지고 있는 쪽이 서버, 제공받는 쪽이 클라이언트가 됩니다.
  • Stateless(무상태)입니다.
  • HTTP 프로토콜을 사용하므로 HTTP 프로토콜처럼 무상태성을 가지고 있습니다.
  • 클라이언트의 context를 서버에 저장하지 않습니다. (서버는 신경쓸 것 없이 본연에 업무에만 집중하면 됩니다.)
  • 서버는 각각에 요청에 대한 응답만 하면 됩니다.

Rest API의 장, 단점

실습

  • Axios - http 통신을 위한 라이브러리 npm install axios
  • Insomnia (PostMan) - rest api 테스트 툴
  • (번외) React Icons npm install react-icons


이런 식으로 react-icons 불러올 수 있음!

async, await

Geolocation 사용!
useEffect 에서 사용되는 함수 자체를 async 로 할 수 없다.

useEffect(async () => {
	await .... // 이런 방식은 동작하지 않음
}, []);
const getGeolocation = async () => {};

useEffect(async () => {
	getGeolocation(); // 이런식으로 사용이 되어야함.
}, []);
  • await 같은 비동기 함수를 활용할때는, try {} catch(e) {} 을 감싸는 것이 좋음
  • api 서버에서 오류를 주거나, 무한 로딩에 빠지는 경우 등을 catch 해서 처리해줘야함!
const getGeolocation = async () => {
	try{
    	navigator.geolocation.getCurrentPosition((position) => {
        	setLat(position.coords.latitude);
            setLon(position.coords.longitude);
        },
        () => {
        	// 에러 콜백
        	alert("위치 정보에 동의 해주셔야 합니다.");
        });
    } catch (e) {
   		console.error(e); // error message
    }    
};
const getWeatherInfo = (_lat, _lon) => {
	...
	return <날씨정보>;
};

함수는 최대한 캡슐화 시켜주는 것이 좋음!!

Promise

function checkPromise() {
  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("완료!"), 1000);
  });

  console.log("1초 대기");
  let result = promise;

  console.log(result);
}

checkPromise();

async function checkPromise() {
  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("완료!"), 1000);
  });

  console.log("[await] 1초 대기");
  let result = await promise;

  console.log(result);
}
checkPromise();

Promise 함수 사용법!

  • resolve 콜백함수에, value를 넣어서 반환값 지정
  • reject 콜백함수에, value 넣어서 예외때 반환값

api key 값 보안

API KEY 같은 경우는, 외부로 유출되면 안되는 값이므로, 밖에서 보이지 않게 관리하는 것이 좋음

const getWeatherInfo = async () => {
    try {
      await axios.get(
        `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${process.env.REACT_APP_WEATHER_API}&units=metric`
      );
    } catch (error) {
      console.error(error);
    }
  };

process.env.REACT_APP_WEATHER_API 를 통해 외부에서 입력 가능!

< .env >

REACT_APP_WEATHER_API=<YOUR_API_KEY>

주의! REACT_APP 을 앞에 꼭 붙혀주어야함!

  • .gitignore 파일에 .env 를 추가해주어야함!! (숨기는 의미가 없어짐)

API response error catch

    const response = await axios.get(<Get 요청 Url>);
    
	if (response.status !== 200) {
        alert("날씨 정보를 가져오지 못했습니다.");
        return;
    }

보통 data가 없을때 2xx 서버 오류를 많이 만들어낸다!
weather의 경우! 200!

API 테스트 툴

PostMan, Insomnia 같은 것들로 ㄱㄱ

const response = await axios.post("https://holy-fire-2749.fly.dev/chat",
      { question: "안녕?", },
      { headers: { Authorization: "Bearer BLOCKCHAINSHCOOL3" }
  });

코드로는 이런 형태를 띈다!

Chat GPT part

< Card.jsx >

const Chat = () => {
  const [question, setQuestion] = useState("");
  const [content, setContent] = useState("");
  const [isLoading, setIsLoading] = useState(false);

  const onSubmitChat = async (e) => {
    try {
      e.preventDefault();

      if (isLoading) {
        alert("검색중입니다...");

        return;
      }
      if (!question) {
        alert("질문을 입력해주세요.");

        return;
      }

      setIsLoading(true);
      setContent("");

      const response = await axios.post(
        "https://holy-fire-2749.fly.dev/chat",
        {
          //   question: `${question}`,
          //   question: question,
          question,
        },
        {
          headers: {
            Authorization: "Bearer BLOCKCHAINSCHOOL3",
          },
        }
      );

      if (response.status !== 200) {
        alert("오류가 발생했습니다.");
        setIsLoading(false);

        return;
      }

      console.log(response);
      setContent(response.data.choices[0].message.content);

      setIsLoading(false);
    } catch (error) {
      console.error(error);

      setIsLoading(false);
    }
  };

  return (
    <div className="bg-black min-h-screen flex flex-col justify-center items-center text-white">
      <form onSubmit={onSubmitChat}>
        <input
          className="text-black"
          type="text"
          value={question}
          onChange={(e) => setQuestion(e.target.value)}
        />
        <input type="submit" value="검 색" />
      </form>
      {content && <div className="mt-4 px-16">{content}</div>}
    </div>
  );
};

export default Chat;

preventDefault()Enter 를 눌렀을때 자동으로 submit이 실행되는 것을 막기 위해!!
Enter 를 누르면, 자동으로 submit 이 되는 것이 default

백엔드 Node js 세팅

npm install express --save

< package.json >

{
  "name": "node_test",
  "version": "1.0.0",
  "description": "changer",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "changer",
  "license": "MIT",
  "dependencies": {
    "express": "^4.18.2"
  }
}

Module System 이란?

  • 모듈 시스템 등장 이전의 자바스크립트 개발은
    < script src='…' > 로 불러와야 했습니다.
  • 모듈 시스템의 등장으로 보기에 직관적이고 효율성 있게 됨
  • 가장 많이 쓰이는 ES6CommonJS
  • 우리는 CommonJS 로 사용

< a.js >

function goModule() {
  console.log("Hello, Module!");
}

// export default goModule;
module.exports = goModule;

< b.js >

const goModule = require("./a");

goModule();

node b.js 입력

서버 세팅

CommonJS 방식으로, express 를 불러오기
< app.js >

const express = require("express");

const app = express(); // get express

const port = 3010; // server port num

app.get("/", (req, res) => {
  res.send("Hellow, Express!!");
}); // handler

app.listen(port, () => {
  console.log(`Server listening on port ${port}`);
});

get 요청 (req, res) 파라미터를 받아, 요청을 처리함!

node app.js 로 실행

  • post의 경우!
app.post("/", (req, res) => {
  res.send("This is Post Request");
});

  • 그 외

한번더 리마인드

  • 조회 : Get
  • 생성 : Post
  • 업데이트 : Put
  • 삭제 : Delete
  • url path
app.get("/abc", (req, res) => {
  res.send("Hello, ABC ABC!!");
});

profile
this too shall pass

0개의 댓글