Post

CarrotMkt Clone Coding_POST

✅ Request Body

When you need to send data from a client (let’s say, a browser) to your API, you send it as a request body.

✅ HTML

1️⃣ HTML로 form tag그리고 안에 input을 만들어 user로부터 정보를 입력받는다.

  • 이 때 database에 주었던 column명과 HTML의 title, id 일치하게
1
2
3
4
5
6
7
<form action="write-form">
  <h1>Upload your item here</h1>
  <div>
    <label for="image">image</label>
    <input type="file" id="image" name="image" />
  </div>
</form>

BE(PYTHON) POST in backend

정보를 backend server에 올려두기

2️⃣ 서버에 정보를 POST(업로드)

1
2
@app.post('/경로')
    def 함수이름 (내가 받아오고 싶은 ):
1
2
3
4
5
6
7
8
@app.post('/items')
    def create_item(image: UploadFile,
                    title: Annotated[str, Form()],
                    price: Annotated[int, Form()],
                    description: Annotated[str, Form()],
                    place: Annotated[str, Form()],
                    insertat: Annotated[int, Form()]
                    ):

FE(JS) 받은 정보 FE에서 server로 전달

HTML에서 submit하면 JS에서 handleSubmit함수 실행

form.addEventListener("submit", handleSubmit);

submit이라는 이벤트는 제출 후 페이지를 reload 이를 방지하기 위해 preventDefault()

1
event.preventDefault();

fetch

1
2
3
4
5
6
7
8
9
10
11
12
const form = documet.getElementById("write-form");

const handleSubmit = async (evnet) => {
  event.preventDefault();
  const body = new FormData(form);
  await fetch("/itmes", {
    method: "POST",
    body: body
  });
};

form.addEventListener("submit", handleSubmit);

const body= new FormData(form)

  • 여기서 new FormData는 JS 내장 객체
  • POST의 body를 FormData로 묶어서 보낸다는 뜻
  • form은 우리가 위에서 선언해 준 변수

BE(PYTHON) SQL lite 연결하기

SQLITE settings

  • 전체 문서에서 한 번만 하면 됨.
1
2
con= sqlite3.connect("db.db", check_smae_thread= False)
cur= con.cursor()

BE(PYTHON) 받은 정보 database에 저장 insert in database

이미지(blob) 크기 떄문에 읽어올 시간 필요

1
2
3
4
5
6
7
8
9
@app.post('./items')
    def create_item(image: UploadFile,
                    title: Annotated[str, Form()],
                    price: Annotated[int, Form()],
                    description: Annotated[str, Form()],
                    place: Annotated[str, Form()]
                    ):

    image_bytes= await image.read()

SQL문법을 사용해 BE에서 받아온 data를 SQLITE database에 insert

특히 이미지는 16진법으로 바꿔줌 주의!

image_bytes.hex()

1
2
3
4
5
6
7
8
9
    # 여기는 SQL
    cur.execute(f"""
                INSERT INTO items(title, image, price, description, place, insertat)
                VALUES ("{title}", "{image_bytes.hex()}", {price}, "{description}", "{place}", {insertat})
    """)

    con.commit()
    print(image, title, price, description, place, insertat)
    return "200"

☑️ BE python code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  @app.post("/items")
async def create_item(image:UploadFile,
                title: Annotated[str, Form()], #form형식으로 str으로 정보가 올 것이다.
                price: Annotated[int, Form()],
                description: Annotated[str, Form()],
                place: Annotated[str, Form()],
                insertat: Annotated[int, Form()]
                ):

    #image is very big, so time necessary to read
    image_bytes= await image.read()
    #insert in database
    #""""""is like backtick in js
    #hex는 16진법으로 바꿔주는 기능
    cur.execute(f"""
                INSERT INTO items(title, image, price, description, place, insertat)
                VALUES ("{title}", "{image_bytes.hex()}", {price}, "{description}", "{place}", {insertat})
                """)
    con.commit()

    print(image, title, price, description, place, insertat)
    return "200"

FE(JS) backend의 응답 가져오기

우리는 insertat(입력한 시간)도 넣고 싶음.

얘는 db에서 받는 거 아니고 지금 시간 append

1
body.append("insertat", new Date().getTime());

💡 try, catch

방금 BE에서 return "200"했잖아 if, else도 좋지만
try, catch구문을 사용해서
try ⭕️ => item 서버에 POST => return 200 성공적으로 받았음 => window.location.pathname= "/login.html"; try ❌ => catch => console.log에 error보여주는 console.error

🍯 try, catch는 어디서 불러와야 할까? item POST하는 것을 try, POST에 실패하면 catch

1
2
3
4
5
6
7
    const data= await res.json();

if(data === "200")
    //응답이 200이면 다시 root로 돌리기
    window.location.pathname= "/login.html";
    } catch (e){
        console.error(e);

☑️ FE JS code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
async function handleSubmitForm(event) {
  event.preventDefault();

  const body = new FormData(form);
  body.append("insertat", new Date().getTime());

  //try catch 구문 사용, try and if it doesnt work, e in catch
  try {
    //post item on server
    const res = await fetch("/items", {
      method: "POST",
      body: body
    });

    //to go back to root page after uploading item
    const data = await res.json();
    if (data === "200") window.location.pathname = "/login.html";
  } catch (e) {
    console.error(e);
  }

  console.log("submitted");
}

const form = document.getElementById("write-form");
form.addEventListener("submit", handleSubmitForm);
This post is licensed under CC BY 4.0 by the author.