๐Ÿ˜‚Hackathon ๋งˆ๊ฐ์ผ์„ ๋†“์ณค์ง€๋งŒ, ๋” ํฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์–ด์š”: ์˜ฌ๋ฐ”๋ฅธ Project Partner ์ฐพ๊ธฐ

๋ฐœํ–‰: (2025๋…„ 12์›” 23์ผ ์˜คํ›„ 04:52 GMT+9)
6 min read
์›๋ฌธ: Dev.to

Source: Dev.to

์•„์ด๋””์–ด๋Š” ์žˆ์Šต๋‹ˆ๋‹ค.
์Šคํ‚ฌ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
๋™๊ธฐ๋ถ€์—ฌ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ๋„โ€ฆ ์—ฌ์ „ํžˆ ํ˜ผ์ž์„œ ๊ฐœ๋ฐœํ•˜๊ณ  ์žˆ์ฃ .

๊ทธ๋ž˜์„œ ์ €๋Š” Projura๋ฅผ ๋งŒ๋“ค๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค โ€” ๊ฐœ๋ฐœ์ž, ๋””์ž์ด๋„ˆ, ๊ทธ๋ฆฌ๊ณ  ์ œ์ž‘์ž๋“ค์ด ๋ฌด์ž‘์œ„ ํŒ€์›์ด ์•„๋‹ˆ๋ผ ์ ํ•ฉํ•œ ํ”„๋กœ์ ํŠธ ํŒŒํŠธ๋„ˆ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ์•ฑ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ๋งŒ๋“ค๋ฉด์„œ ์‹ค์ œ ํ˜‘์—… ์•ฑ์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค.

Projura๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

  • โœ… ํ”„๋กœํ•„ ๋งŒ๋“ค๊ธฐ
  • โœ… ๊ธฐ์ˆ  ์ถ”๊ฐ€
  • โœ… ํ”„๋กœ์ ํŠธ ์•„์ด๋””์–ด ๊ฒŒ์‹œ
  • โœ… ๊ธฐ์ˆ  ๊ธฐ๋ฐ˜์œผ๋กœ ํ˜‘์—…์ž๋ฅผ ๋งค์นญ
  • โœ… ํ˜ผ์ž์„œ ๋งŒ๋“ค๊ธฐ๋ฅผ ๋ฉˆ์ถ”์„ธ์š”

๊ฐ€์งœ ๋„คํŠธ์›Œํ‚น์€ ์—†์Šต๋‹ˆ๋‹ค. ๋์—†๋Š” DM๋„ ์—†์Šต๋‹ˆ๋‹ค. ์˜ค์ง ๊ธฐ์ˆ  ๊ธฐ๋ฐ˜ ํ˜‘์—…๋งŒ.

ํ•ต์‹ฌ ์•„์ด๋””์–ด: ์ฝ”๋”ฉ์ฒ˜๋Ÿผ ์‚ฌ๋žŒ ๋งค์นญํ•˜๊ธฐ

Projura๋Š” ์‚ฌ๋žŒ์„ ๋ฌด์ž‘์œ„๋กœ ๋งค์นญํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ตฌ์กฐํ™”๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค:

  • ์‚ฌ์šฉ์ž ๊ธฐ์ˆ 
  • ํ”„๋กœ์ ํŠธ ์š”๊ตฌ์‚ฌํ•ญ

์†Œํ”„ํŠธ์›จ์–ด๋Š” ๋ถ„์œ„๊ธฐ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๊ณ  โ€” ๋…ผ๋ฆฌ๋ฅผ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค.

Step 1: ์‚ฌ์šฉ์ž ํ”„๋กœํ•„ ์ƒ์„ฑ (๋ฐฑ์—”๋“œ ๋กœ์ง)

ํ”„๋ก ํŠธ์—”๋“œ (JavaScript)

async function createUser() {
  const res = await fetch("http://127.0.0.1:5000/users", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      name: name.value,
      bio: bio.value,
      skills: skills.value
    })
  });

  const data = await res.json();
  userId = data.id;
}

๋ฐฑ์—”๋“œ (Flask API)

@app.route("/users", methods=["POST"])
def create_user():
    data = request.json
    user = User(
        name=data["name"],
        bio=data["bio"],
        skills=data["skills"]
    )
    db.session.add(user)
    db.session.commit()
    return jsonify({"id": user.id})

์ด๊ณณ์ด Projura๊ฐ€ ๊ณต์‹์ ์œผ๋กœ ๋‹น์‹ ์˜ ์กด์žฌ๋ฅผ ์ธ์‹ํ•˜๋Š” ์ˆœ๊ฐ„์ž…๋‹ˆ๋‹ค.

Step 2: ์‚ฌ์šฉ์ž ๋ชจ๋ธ (๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜๋Š” ๊ณณ)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100))
    bio = db.Column(db.Text)
    skills = db.Column(db.Text)

์Šคํ‚ฌ์€ ์‰ผํ‘œโ€‘๊ตฌ๋ถ„ ๊ฐ’์œผ๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค, ์˜ˆ์‹œ:

"python, flask, frontend"

์ €์žฅํ•˜๊ธฐ ์‰ฝ๊ณ  ๋น„๊ตํ•˜๊ธฐ๋„ ์‰ฝ์Šต๋‹ˆ๋‹ค.

Step 3: ํ”„๋กœ์ ํŠธ๋Š” ์š”๊ตฌ ์‚ฌํ•ญ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค

class Project(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(150))
    description = db.Column(db.Text)
    required_skills = db.Column(db.Text)

์ด์ œ ํ”„๋กœ์ ํŠธ๋Š” ์‚ฌ์šฉ์ž์™€ ๋™์ผํ•œ ์–ธ์–ด์ธ ์Šคํ‚ฌ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Step 4: ๋งค์นญ ๋กœ์ง (์Šค๋งˆํŠธ ํŒŒํŠธ)

from difflib import SequenceMatcher

def skill_match(a, b):
    return SequenceMatcher(None, a, b).ratio()

์šฐ๋ฆฌ๋Š” ์‚ฌ์šฉ์ž ์Šคํ‚ฌ๊ณผ ํ”„๋กœ์ ํŠธ ์Šคํ‚ฌ์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค; ์œ ์‚ฌ๋„ ๋น„์œจ์ด ๋†’์„์ˆ˜๋ก ๋” ์ข‹์€ ๋งค์น˜๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํ˜‘์—…์„ ๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์˜์‚ฌ๊ฒฐ์ •์œผ๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

5๋‹จ๊ณ„: ํ”„๋ก ํŠธ์—”๋“œ์™€ ๋ฐฑ์—”๋“œ๊ฐ€ ์ผ์น˜ํ•ด์•ผ ํ•จ

fetch(`${API}/projects/${userId}`)
  .then(res => res.json())
  .then(data => {
    projects.innerHTML = data.map(p =>
      `- ${p.title}
`
    ).join("");
  });

API๋Š” ๊ณ„์•ฝ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ๊นจ๋ฉด ์•„๋ฌด๊ฒƒ๋„ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‹จ๊ณ„ 6: ๋””๋ฒ„๊น… = ์‹ค์ œ ํ•™์Šต

Typical problems I hit:

  • โŒ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ด๋„ ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š์Œ
  • โŒ API๋ฅผ ํ˜ธ์ถœํ–ˆ์ง€๋งŒ 500 ์˜ค๋ฅ˜ ๋ฐ˜ํ™˜
  • โŒ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ ๋ถˆ์ผ์น˜
  • โŒ CORS๊ฐ€ ์š”์ฒญ์„ ์ฐจ๋‹จ

Each error forced me to learn:

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š์Œ
  • ํ”„๋ก ํŠธ์—”๋“œ์™€ ๋ฐฑ์—”๋“œ๊ฐ€ ์ผ์น˜ํ•ด์•ผ ํ•˜๋Š” ์ด์œ 
  • ๋กœ๊ทธ๊ฐ€ ์ค‘์š”ํ•œ ์ด์œ 
  • โ€œ๋™์ž‘ํ•œ๋‹คโ€์™€ โ€œ์ž‘๋™ํ•œ๋‹คโ€๋Š” ๋‹ค๋ฆ„

This is where theory becomes engineering.

์™œ Projura๊ฐ€ ์ค‘์š”ํ•œ๊ฐ€

  • ์ดˆ๋ณด์ž๋“ค์€ ํŒ€์›์„ ์ฐพ๋Š” ๋ฐ ์–ด๋ ค์›€์„ ๊ฒช๋Š”๋‹ค
  • ์ˆ™๋ จ๋œ ์‚ฌ๋žŒ๋“ค์€ ์ข…์ข… ํ˜ผ์ž ์ž‘์—…ํ•œ๋‹ค
  • ํ›Œ๋ฅญํ•œ ์•„์ด๋””์–ด๊ฐ€ ์ผ์ฐ ์‚ฌ๋ผ์ง„๋‹ค

Projura๋Š” ์‚ฌ๋žŒ๋“ค์ด ์‹ค์ œ๋กœ ํ•จ๊ป˜ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์— ๊ธฐ๋ฐ˜ํ•ด ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€๋Šฅํ•œ ํ–ฅํ›„ ์—…๊ทธ๋ ˆ์ด๋“œ

  • ๐Ÿ”ฅ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…
  • ๐Ÿ”ฅ GitHub ํ†ตํ•ฉ
  • ๐Ÿ”ฅ ์ถ”์ฒœ ์ ์ˆ˜ ๋งค๊ธฐ๊ธฐ
  • ๐Ÿ”ฅ ํ”„๋กœ์ ํŠธ ์ผ์ •
  • ๐Ÿ”ฅ ํŒ€ ๋Œ€์‹œ๋ณด๋“œ

๊ฐ ๊ธฐ๋Šฅ์€ Projura๋ฅผ ํ”„๋กœ๋•์…˜์— ๋” ๊ฐ€๊น๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์ตœ์ข… ์ƒ๊ฐ

Projura๋Š” ๋‚˜์—๊ฒŒ ์ค‘์š”ํ•œ ๊ฒƒ์„ ๊ฐ€๋ฅด์ณ ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค: ์•ฑ์€ ์ฝ”๋“œ์— ๊ด€ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ธ๊ฐ„์˜ ๋ฌธ์ œ๋ฅผ ๋…ผ๋ฆฌ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์„ ์˜๋ฏธ ์žˆ๊ฒŒ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ์Šคํ…œ์„ ์„ค๊ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ๋‹จ์ˆœํžˆ ์ฝ”๋”ฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์˜ํ–ฅ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

# coders language 
print("Happy building ๐Ÿš€๐Ÿ’ป ")
Back to Blog

๊ด€๋ จ ๊ธ€

๋” ๋ณด๊ธฐ ยป

2026๋…„ ๊ธฐ์ˆ ์— ๋Œ€ํ•œ ๋‚˜์˜ ๋ชฉํ‘œ

2026๋…„ ๊ธฐ์ˆ  ๋ชฉํ‘œ 1. Dev Community์— ๋” ๋งŽ์€ ์ฝ˜ํ…์ธ  ๊ฒŒ์‹œํ•˜๊ธฐ ์—ฌ๊ธฐ์„œ ๊ณ„์† ๊ธ€์„ ์“ฐ๋ฉด์„œ ๋‚ด๊ฐ€ ๋ฐฐ์šฐ๊ณ  ์žˆ๋Š” ๊ธฐ์ˆ ์„ ๊ณต์œ ํ•˜๊ณ  ์˜์–ด ์—ฐ์Šต๋„ ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

Micro Frontend Architecture, BFF, and Microservices โ€” ์‹ค์ œ ์‚ฌ๋ก€๋ฅผ ํ†ตํ•ด ์‰ฝ๊ฒŒ ์„ค๋ช…

Netflix, Amazon, Uber, ๊ทธ๋ฆฌ๊ณ  LinkedIn๊ณผ ๊ฐ™์€ ํ˜„๋Œ€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ Microservices, Micro Frontends, ๊ทธ๋ฆฌ๊ณ  Backend for Frontend (BFF) ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์ถ•๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ด๋Ÿฌํ•œโ€ฆ

์™œ ๋‚˜๋Š” ๋น„์‹ผ ์ œํ’ˆ์ด ๊ฐ€๋“ํ•œ ์‹œ์žฅ์—์„œ ๋ฌด๋ฃŒ Accessibility Widget์„ ๋งŒ๋“ค์—ˆ๋Š”๊ฐ€

์™œ ์›น ์ ‘๊ทผ์„ฑ์ด ๋‚˜์—๊ฒŒ ๊ฐœ์ธ์ ์ธ ์˜๋ฏธ๊ฐ€ ๋˜์—ˆ๋Š”๊ฐ€ ์ œ ์ด๋ฆ„์€ ๋ณด๋‹จ์ด๊ณ , ์žฅ์•  ๋ถ„์•ผ์—์„œ ๋น„์˜๋ฆฌ ์กฐ์ง์—์„œ ์ผํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋งค์ผ ์ €๋Š” ์‚ฌ๋žŒ๋“ค์ดโ€ฆ