Skip to content

yongseokcho/bixby

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

29 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

์š”๋ฆฌ๋ณด๊ณ 

"์•ˆ๋…•ํ•˜์„ธ์š”. ๊ฐœ๋ฐœ์ž์—๊ฒ ์ฆ๊ฑฐ์›€์„, ์‚ฌ์šฉ์ž์—๊ฒ ํŽธ๋ฆฌํ•จ์„ ์„ ๋ฌผํ•˜๋Š” ์š”๋ฆฌ๋ณด๊ณ  ํŒ€์ž…๋‹ˆ๋‹ค."

๋ชฉ์ฐจ

  1. ์บก์А๊ตฌ์กฐ
  2. ์บก์А์„ค์ •
  3. ์‚ฌ์ „(Dictionary)
  4. ๋ฐœํ™”(Training)
  5. ํŠธ๋žœ์žญ์…˜
  6. ๋ ˆ์ด์•„์›ƒ
  7. ์—๋Ÿฌ์ฒ˜๋ฆฌ
  8. HTTP ์š”์ฒญ
  9. ์™ธ๋ถ€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰
  10. ๋ถ€๋ก

์บก์А๊ตฌ์กฐ

์บก์А์€ ํฌ๊ฒŒ assets, code, models, resources ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆ„์ ธ ์žˆ๋Š”๋ฐ assets ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” ์ •์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ํŒŒ์ผ(์ด๋ฏธ์ง€)์ด ์ €์žฅ๋˜์–ด์žˆ๊ณ , code ๋ถ€๋ถ„์€ .js ํŒŒ์ผ๋“ค์„ ๊ฐ ๊ธฐ๋Šฅ์— ๋งž๊ฒŒ ํด๋”๋ฅผ ๋งŒ๋“ค์–ด์„œ ๊ตฌ์„ฑ์„ ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€ ํŒŒ์ผ๋งŒ ์žˆ๋Š” assets๊ณผ .js ํŒŒ์ผ์ด ์žˆ๋Š” code์„ ์ œ์™ธํ•˜๊ณ  ๋‚˜๋จธ์ง€ ํด๋”๋“ค์˜ ๊ตฌ์กฐ์— ๋Œ€ํ•ด์„œ ์„ค๋ช…์„ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

models

๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ธ

  • actions : /base, /exercise, /guide, /process, /recipe
  • concepts : /api, /base, /commit, /exercise, /guide, /ingredient, /process, /recipe

์„ค๋ช…

actions ํด๋”์—๋Š” ๊ฐ ๊ธฐ๋Šฅ์— ํ•„์š”ํ•˜๋Š” ์•ก์…˜๋“ค๊ณผ concepts ํด๋”์—๋Š” ์•ก์…˜์—์„œ ์‚ฌ์šฉ๋  ๋ชจ๋ธํƒ€์ž…๋“ค๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. base ํด๋”์—๋Š” ๋ฒ”์šฉ์„ฑ์ด ๋†’๊ฑฐ๋‚˜ ๋…๋ฆฝ์ ์ธ ํŒŒ์ผ๋“ค์ด ์žˆ๊ณ  ๋‚˜๋จธ์ง€ ํด๋”๋“ค์€ ์ด๋ฆ„์— ์—ฐ๊ด€์„ฑ์ด ์žˆ๋Š” ํŒŒ์ผ๋“ค์„ ํฌํ•จ์‹œ์ผœ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

concepts ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” structure๋ผ๋Š” ๋‹ค์ˆ˜์˜ model๋“ค์„ ํฌํ•จํ•˜๋Š” ํƒ€์ž…์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์š”๋ฆฌ๋ณด๊ณ ์—์„œ๋Š” primitive type๊ณผ structure๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด ์œ„์™€ ๊ฐ™์ด structure ๋ผ๋Š” ํด๋”๋ฅผ ๋งŒ๋“ค์–ด์„œ ํ•ด๋‹น ํด๋” ์•ˆ์— ์ƒ์„ฑ์„ ํ•˜์—ฌ ๊ด€๋ฆฌ๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

resources

๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ธ

  • base : endpoints.bxb
  • ko-KR : training, /dialogs, /layouts, /transactions, /views, /voca, Yoribogo.hints.bxb, capsule-info.bxb, capsule.properties

์„ค๋ช…

ko-KR ํด๋”๋Š” ํ•œ๊ตญ์–ด์™€ ๊ด€๋ จ๋œ resources๋ฅผ ๋ชจ์•„๋†“์€ ํด๋”์ž…๋‹ˆ๋‹ค. ๋งˆ์ผ“ ํ”Œ๋ ˆ์ด์Šค์—์„œ ํ•ด๋‹น ์บก์А์˜ ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค์ฃผ๋Š” .hints.bxb ์™€ ๋ฐœํ™”๋ฅผ ํ•™์Šตํ•˜๋Š” training ํŒŒ์ผ, ํŠน์ • ๋ฐœํ™”์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•˜๋Š” ํŒŒ์ผ๋“ค์„ ๋ชจ์•„ ๋†“์€ layouts , views ํด๋”, ๋™์˜์–ด ์ฒ˜๋ฆฌ๋‚˜ ํŠน์ • ๋‹จ์–ด๋ฅผ ๋น…์Šค๋น„์—๊ฒŒ ํ•™์Šต์‹œํ‚ค ์œ„ํ•œ ๋‹จ์–ดํŒŒ์ผ์„ ๋ชจ์•„๋†“์€ voca ํด๋” ๋“ฑ์œผ๋กœ ๊ตฌ์„ฑ์„ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

capsule.properties ์€ HTTP ์š”์ฒญ์— ํ•„์š”ํ•œ ์„œ๋ฒ„์˜ ์ฃผ์†Œ, API ํ‚ค๊ฐ’์ด๋‚˜ ๊ถŒํ•œ ๋ฒ”์œ„ ๋“ฑ ์บก์А์„ ๊ตฌ์„ฑํ•  ๋•Œ ํ•„์š”ํ•œ ๊ฐ’๋“ค์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์™ธ์˜ ํŒŒ์ผ๋“ค์— ๋Œ€ํ•ด์„œ๋Š” ์บก์А์„ค์ • ๋ถ€๋ถ„์—์„œ ๋‹ค์‹œ ์–ธ๊ธ‰ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์บก์А์„ค์ •

๋น…์Šค๋น„ ์บก์А์„ ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ํ•„์š”ํ•˜๊ฑฐ๋‚˜ ๋„์›€์ด ๋˜๋Š” ์„ค์ •๋“ค์— ๋Œ€ํ•ด์„œ ๋ง์”€๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

.hints.bxb

 uncategorized{
   utterance (์‚ฌ์šฉ๋ฒ• ๊ฐ€๋ฅด์ณ์ค˜)
   utterance (๋ฏธ์—ญ์ด๋ž‘ ์‡ ๊ณ ๊ธฐ ์š”๋ฆฌ๋ฒ• ์ฐพ์•„์ค˜)
   utterance (๋ณด์Œˆ๊น€์น˜ ๋ ˆ์‹œํ”ผ ๋ณด์—ฌ์ค˜)
   utterance (300์นผ๋กœ๋ฆฌ ์ด์ƒ ๋ ˆ์‹œํ”ผ ๋ณด์—ฌ์ค˜)
 }

hints.bxb ํŒŒ์ผ ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” ์บก์А์ด ์‹ค์ œ ๋งˆ์ผ“ ํ”Œ๋ ˆ์ด์Šค์— ์—…๋กœ๋“œ ๋˜์—ˆ์„ ๋•Œ ์‚ฌ์šฉ์ž๋“ค์—๊ฒŒ ๋Œ€ํ‘œ๋ฐœํ™” ์˜ˆ์ œ๋กœ ๋ณด์—ฌ์ค„ ๋ฐœํ™” ๋ฆฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค. (์ œ์ผ ๋จผ์ € ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐœํ™”๋“ค์ด๊ธฐ ๋•Œ๋ฌธ์— ์ถฉ๋ถ„ํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ๊ฑฐ์ณ์•ผํ•ฉ๋‹ˆ๋‹ค.) ์œ„์™€ ๊ฐ™์ด ์ž…๋ ฅํ•œ ํ›„ ์บก์А์ด ๋งˆ์ผ“ ํ”Œ๋ ˆ์ด์Šค์— ๋“ฑ๋ก ๋œ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ํ™•์ธ ํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

utterance(...) ์•ˆ์— ๋„ฃ์€ ๋ฐœํ™” ์•ž์— "์š”๋ฆฌ๋ณด๊ณ ์—์„œ, " ๋ผ๋Š” ๋ฌธ์žฅ์ด ๋“ค์–ด๊ฐ„ ๊ฒƒ์„ ๋ณด์‹ค ์ˆ˜ ์žˆ๋Š”๋ฐ, ํ•ด๋‹น ๋ถ€๋ถ„์€ ์บก์А ์ด๋ฆ„์œผ๋กœ capsule.bxb ์— ์ž…๋ ฅํ•œ ๋ณ„์นญ์— ๋”ฐ๋ผ ์ž๋™์ ์œผ๋กœ ๋“ค์–ด๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

capsule-info.bxb

capsule-info {
  display-name (์š”๋ฆฌ๋ณด๊ณ )
  ...
  dispatch-aliases{
   alias (์š”๋ฆฌ ๋ณด๊ณ )
  }
  ...

capsule-info.bxb ํŒŒ์ผ์€ ์บก์А์˜ ๋ณ„์นญ์„ dispatch-aliases{...} ์— ์ž…๋ ฅํ•˜์—ฌ ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ €ํฌ ์บก์А ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” ์š”๋ฆฌ ๋ณด๊ณ  ์ธ๋ฐ, ๋ฐœ์Œํ•˜๊ธฐ ์–ด๋ ค์šด ๋‹จ์–ด๋“ค์€ ๋น…์Šค๋น„๊ฐ€ ์ธ์‹ํ•˜๊ธฐ ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์— ๋˜๋„๋ก์ด๋ฉด ์‰ฝ๊ณ  ๊ฐ„๋‹จํ•œ ๋ณ„์นญ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

capsule.properties

์บก์А ๊ฐœ๋ฐœ ๋„์ค‘ HTTP ์š”์ฒญ์„ ํ•˜๋Š” ๋ฉ”์†Œ๋“œ๊ฐ€ ๋งŽ์•„์ง€๊ณ  ์—ฌ๋Ÿฌ ํŒŒ์ผ๋กœ ๋‚˜๋ˆ„์–ด ์ง€๋Š” ๊ฒฝ์šฐ ๊ธด ์›น์„œ๋ฒ„ ์ฃผ์†Œ๋ฅผ ๋ฒˆ๊ฑฐ๋กญ๊ฒŒ ๊ณ„์† ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฑฐ๊ธฐ๋‹ค๊ฐ€ ์™ธ๋ถ€ API๊นŒ์ง€ ์‚ฌ์šฉ์„ ํ•˜๊ฒŒ๋˜๋ฉด key๊ฐ’์„ ์–ด๋””์— ์ €์žฅํ• ์ง€๋„ ๊ณ ๋ฏผํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿด๋•Œ ์ „์—ญ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ ์–ธํ•ด์ฃผ๋Š” ํŒŒ์ผ์ด ์žˆ๋Š”๋ฐ, ๊ทธ๊ฒŒ ๋ฐ”๋กœ capsule.properties ์ž…๋‹ˆ๋‹ค.

## Set the config mode of this capsule
# capsule.config.mode=default

## Set configuration properties with `config.<mode>.<propertyKey>=<propertyValue>`
## Use mode `default` for fallback property values
# config.default.my.property.key=myValue 123

# URL ์ฃผ์†Œ ์˜ˆ์‹œ
config.default.remote.url=http://example:1234/mywebserver/

์œ„ ์ฝ”๋“œ์˜ˆ์‹œ๋Š” ์ €ํฌ ์š”๋ฆฌ๋ณด๊ณ ์—์„œ๋„ ์‚ฌ์šฉ์ค‘์ธ ํ˜•์‹์˜ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์œ„์™€ ๊ฐ™์ด ์„ ์–ธ์„ ํ•ด์ฃผ๊ณ  ์‹ค์ œ .js ํŒŒ์ผ์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ํ˜ธ์ถœํ•˜์—ฌ ์„ ์–ธํ•œ ๋ณ€์ˆ˜๋ฅผ ์ „์—ญ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

var config = require('config');
...
module.exports.ExampleMethod = function(){
  return http.getUrl(config.get('remote.url') + 'helloworld/', { format: 'json' });
}

capsule.bxb

์บก์А์„ ๊ฐœ๋ฐœํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์–ด๋–ค ์–ธ์–ด๋“ค์— ๋Œ€ํ•ด์„œ ์„œ๋น„์Šค ํ•  ๊ฒƒ์ธ์ง€, ๋ฒ„์ „์€ ๋ช‡์œผ๋กœ ํ•˜๊ณ  ๋น…์Šค๋น„์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์บก์А์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด capsule.bxb ์— ์ž…๋ ฅํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

capsule {
  id (mycapsule)
    
  # ์บก์А ๋“ฑ๋ก์‹œ ๋™์ผํ•œ ๋ฒ„์ „์œผ๋กœ๋Š” ์—…๋กœ๋“œ๋ฅผ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  # ๋“ฑ๋กํ•˜์‹ค๋•Œ ์ฃผ์˜ํ•˜์„ธ์š”!
  version (1.2.3)
  format (3)
    
  # ์–ด๋–ค ์–ธ์–ด๋ฅผ ์„œ๋น„์Šค ํ•  ๊ฒƒ์ธ์ง€ ์„ ํƒ ํ•ฉ๋‹ˆ๋‹ค.
  targets {
    target (bixby-mobile-ko-KR)
  }
   
  # ํ•ด๋‹น ์บก์А์ด ์–ด๋–ค ๋ฒ”์ฃผ์— ๋“ค์–ด๊ฐ€๋Š”์ง€ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  store-sections{
    section (FoodAndDrink)
  }
    
  ...

  # ๋น…์Šค๋น„์—์„œ ์ง€์›ํ•˜๋Š” ์บก์А ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์œผ์‹œ๋ฉด
  # ์•„๋ž˜์— ์„ ์–ธํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
  capsule-imports {
    import (viv.core) { 
      as (core) 
    }
    ...
  }
}

id ๋Š” Bixby Developer Center์—์„œ ์„ค์ •ํ•œ ํŒ€์ด๋ฆ„์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋ฒ„์ „ ๋ถ€๋ถ„์€ ์œ„์— ์ฃผ์„์œผ๋กœ ๋‚˜์™€์žˆ์ง€๋งŒ ํ•œ ๋ฒˆ ์˜ฌ๋ผ๊ฐ„ ๋ฒ„์ „์œผ๋กœ๋Š” ๋‹ค์‹œ ๋“ฑ๋ก์„ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. store-sections ๋ถ€๋ถ„์€ ๊ฐœ๋ฐœ ์ค‘์ธ ์บก์А์˜ ์นดํ…Œ๊ณ ๋ฆฌ์— ๋งž๊ฒŒ ์„ ํƒํ•˜์‹œ๋ฉด ๋˜๋Š”๋ฐ ์ข…๋ฅ˜๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ƒ์  ์„น์…˜ ์ข…๋ฅ˜

  • ArtAndLifestyle
  • BusinessAndFinance
  • Communication
  • EducationAndReference
  • FoodAndDrink
  • GamesAndFun
  • HealthAndFitness
  • Local
  • MoviesAndTV
  • MusicAndAudio
  • NewsAndMagazines
  • Photography
  • Productivity
  • Shopping
  • Sports
  • TravelAndTransportation
  • Weather

capsule-imports ๋ถ€๋ถ„์€ ๋น…์Šค๋น„์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๊ฐ™์€ ์บก์А์„ ์‚ฌ์šฉํ• ๋•Œ ์„ ์–ธ์„ ํ•˜๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์ •๋ณด๋Š” https://bixbydevelopers.com/dev/docs/dev-guide/developers/library ๋ฅผ ์ฐธ์กฐํ•ด์ฃผ์„ธ์š”.

์‚ฌ์ „

์‚ฌ์ „์„ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ž์—ด ์ปจ์…‰์€ ์ด 3๊ฐ€์ง€๋กœ enum, name, text ์ž…๋‹ˆ๋‹ค. ์•„๋งˆ ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ์„ธ ๊ฐœ์˜ ํƒ€์ž… ์ค‘์—์„œ ์–ด๋–ค ๊ฒƒ์„ ์„ ํƒํ•ด์•ผํ• ์ง€ ๋งŽ์€ ๊ณ ๋ฏผ์„ ํ•˜์‹ค๊ฑฐ๋ผ๊ณ  ์˜ˆ์ƒ ๋ฉ๋‹ˆ๋‹ค. ์ €ํฌ๋„ ์—ญ์‹œ ์–ด๋–ค ๊ฒƒ์„ ์‚ฌ์šฉํ•ด์•ผ ์ ์ ˆํ•œ์ง€ ํ˜ผ๋™์ด ์™”์—ˆ๋Š”๋ฐ ๋‚˜๋ฆ„๋Œ€๋กœ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์„ ์ด์•ผ๊ธฐ ํ•ด๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

enum name text
Closed type Open type Open type
ํ•œ์ •๋œ ๋ฒ”์œ„๋กœ, ๋‚˜์—ด์ด ๊ฐ€๋Šฅํ•  ๋•Œ ์‚ฌ์šฉ ์ผ๋ถ€๋Š” ๋‚˜์—ด์„ ํ•  ์ˆ˜ ์žˆ์œผ๋‚˜, ์ „๋ถ€ ๋‚˜์—ด์ด ๋ถˆ๊ฐ€๋Šฅ ํ•œ ๊ฒฝ์šฐ ๋ฉ”์‹œ์ง€ ๋‚ด์šฉ์ด๋‚˜ ์ผ์ • ์ œ๋ชฉ๊ณผ ๊ฐ™์ด ์˜ˆ์ธก์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ
Vocab์ด ํ•„์ˆ˜์  Vocab์ด ์„ ํƒ์‚ฌํ•ญ Vocab์„ ๊ฐ€์งˆ ์ˆ˜ ์—†์Œ

enum

๊ด€๋ จ ํŒŒ์ผ

  • ko-KR/voca : AddKeyword.vocab.bxb, RemoveKeyword.vocab.bxb, SearchKeyword.vocab.bxb, LowerBoundKeyword.vocab.bxb, UpperBoundKeyword.vocab.bxb, SortingOption.vocab.bxb, RecipeKeyword.vocab.bxb

enum์„ ์‚ฌ์šฉํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ์˜ˆ์‹œ๋ฅผ ๋“ค์–ด๋ณด์ž๋ฉด **๊ตญ๋‚ด ํ”„๋กœ์•ผ๊ตฌํŒ€**์œผ๋กœ ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋€” ๊ฐ€๋Šฅ์„ฑ์ด ์ ์œผ๋ฉฐ ๋ช…ํ™•ํ•˜๊ณ  ๋ช…์‹œ์ ์œผ๋กœ ์ธ์ง€๊ฐ€ ๋˜๋Š” ๋ฐ์ดํ„ฐ์˜ ์ง‘ํ•ฉ์ผ ๋•Œ, enum์œผ๋กœ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

AddKeyword.vocab.bxb

vocab(AddKeyword) {
  
  "์ถ”๊ฐ€ํ•ด์ค˜" {
    
    "์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”",
    "์ถ”๊ฐ€ํ•ด์ค„๋ž˜",
    "์ถ”๊ฐ€ํ•ด์ฃผ๋ผ",
    "์ถ”๊ฐ€ํ•ด",
    "์ถ”๊ฐ€ํ•ด๋ผ",
    ...
   }

์ €ํฌ ์š”๋ฆฌ๋ณด๊ณ ๋Š” ์žฌ๋ฃŒ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐœํ™”์ธ "์ถ”๊ฐ€ํ•ด์ค˜" ์˜ ๋™์˜์–ด๋“ค์„ ๊ตญ๋ฆฝ๊ตญ์–ด์›์—์„œ ๊ฒ€์ƒ‰ํ•œ ํ›„ ๋‹จ์–ด๋“ค์„ enumํ˜•์‹์œผ๋กœ ์ถ”๊ฐ€๋ฅผ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

name

๊ด€๋ จํŒŒ์ผ

  • ko-KR/voca : Ingredient.vocab.bxb, RecipeName.vocab.bxb

์˜ˆ๋ฅผ๋“ค์–ด ์Œ์‹์ด๊ฑฐ๋‚˜ ์ปดํ“จํ„ฐ ์ฃผ๋ณ€๊ธฐ๊ธฐ ๋“ฑ ์˜๋ฏธ๋Š” ๋ช…ํ™•ํ•˜์ง€ ์•Š์ง€๋งŒ ๋„ˆ๋ฌด ๋งŽ์•„์„œ ๋ชจ๋“  ๊ฒƒ๋“ค์„ ๋‹ค ๋‚˜์—ดํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ์š”? ์ด๋Ÿด ๋•Œ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ๋ชจ๋ธ์ด ๋ฐ”๋กœ name์ž…๋‹ˆ๋‹ค. ์ผ๋ถ€๋Š” ๋‚˜์—ด์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ํ•ด๋‹นํ•˜๋Š” ๋‹จ์–ด๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์•„์„œ ์ „๋ถ€ ๋‚˜์—ด์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ name์ด ํšจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

name์˜ ๊ฒฝ์šฐ enum๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ Vocab์ด ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋‚˜, Vocab์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ ๋น…์Šค๋น„์—๊ฒŒ ์ถ”๊ฐ€์ ์ธ hint๋ฅผ ์คŒ์œผ๋กœ์จ ํƒœ๊น… ์„ฑ๋Šฅ์„ ๋†’ํž ์ˆ˜๋Š” ์žˆ์Šต๋‹ˆ๋‹ค.

์š”๋ฆฌ๋ณด๊ณ  ์ฒ˜๋Ÿผ ์Œ์‹์„ ์˜ˆ๋กœ๋“ค์ž๋ฉด ์น˜ํ‚จ, ์งœ์žฅ๋ฉด, ํ–„๋ฒ„๊ฑฐ ๋“ฑ ์ˆ˜๋งŽ์€ ์Œ์‹ ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ์„ํ…๋ฐ์š”. ๊ณผ์—ฐ ์ง€๊ตฌ์ƒ์— ์กด์žฌํ•˜๋Š” ๋ชจ๋“  ์Œ์‹์˜ ์ด๋ฆ„์— ๋Œ€ํ•ด์„œ ๋ฐœํ™”๋ฅผ ํ•˜๋‚˜ํ•˜๋‚˜ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? ๋ถˆ๊ฐ€๋Šฅ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์œผ๋กœ out of vocab training ์ด๋ผ๋Š” ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Ingredient.vocab.bxb

vocab(Ingredient){
    "๊น€์น˜",
    "๋ผ์ง€๊ณ ๊ธฐ",
    ...
}

์œ„์™€ ๊ฐ™์ด vocab('๋ชจ๋ธ๋ช…')์„ ์„ ์–ธํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ๋ฐœํ™” ํŠธ๋ ˆ์ด๋‹์„ ํ•  ๋•Œ ๊ตฌ๋ถ„์ด ๋˜๋Š” ๋ฌธ์ž ์•ž์— ๋‹จ์–ด๋ฅผ name ๋ชจ๋ธ๋กœ ์„ ์–ธํ•จ์œผ๋กœ์จ ๋ชจ๋“  ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ๋ฐœํ™”๋ฅผ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๊ฒƒ์€ "์žฌ๋ฃŒ๋ช…์œผ๋กœ ๊ฒ€์ƒ‰ํ•˜๊ธฐ" ์—์„œ ์–ธ๊ธ‰ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

text

text๋Š” ์œ„์˜ ๋‘ ๊ฐœ๋กœ๋„ ๋„์ €ํžˆ ๋ฐ์ดํ„ฐ์˜ ํ˜•ํƒœ๋ฅผ ์ •ํ•  ์ˆ˜ ์—†์„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋ธ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋กœ๋“ค์–ด ์•Œ๋žŒ์„ค์ •์ด๋ผ๋Š” ํ‚ค์›Œ๋“œ์— ๋Œ€ํ•ด์„œ ์–ด๋–ค ์‚ฌ๋žŒ์€ "๋‚ด์ผ 8์‹œ 30๋ถ„ ํšŒ์‚ฌ๊ฐ€์•ผํ•ด?" ๋ผ๊ณ  ํ•˜๊ณ  ๋‹ค๋ฅธ ์‚ฌ๋žŒ์€ "๋‚ด์ผ ์ผ์ •" ์ด๋ผ๊ณ  ํ•˜๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ๋ฐœํ™” ๊ทธ๋ฃน์— ๋“ค์–ด์˜ฌ์ง€ ๋ง์ง€๋„ ๋ชจ๋ฅด๊ฒ ๊ณ  ์‚ฌ์ด์ฆˆ๋„ ๋ช…ํ™•ํ•˜์ง€ ์•Š๋‹ค๊ณ  ํ•  ๋•Œ text ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. text๋Š” ์–ด๋– ํ•œ ๊ฐ’์ด๋“  ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ๋ฏธ๋ฆฌ ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, enum, name๊ณผ ๋‹ค๋ฅด๊ฒŒ vocab์„ ๊ฐ€์งˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. (์ €ํฌ ์š”๋ฆฌ๋ณด๊ณ ์—์„œ๋Š” text์˜ ๊ธฐ๋Šฅ์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.)

๋ฐœํ™”

๋น…์Šค๋น„ ์บก์А ๊ฐœ๋ฐœ์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์„ ์ฐจ์ง€ํ•˜๋Š” ์˜์—ญ์€ ๋ฐœํ™”๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” ๋น…์Šค๋น„ ์บก์А ์ž์ฒด๊ฐ€ ๋Œ€ํ™”ํ˜• ํ”Œ๋žซํผ์ด๋ฉฐ ๋ชจ๋“  ๊ธฐ๋Šฅ์˜ ์‹œ์ž‘์ด ๋ฐœํ™”์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๋ฒˆ ํŒŒํŠธ์—์„œ๋Š” ๋ฐœํ™”์— ๋Œ€ํ•ด์„œ ์š”๋ฆฌ๋ณด๊ณ ๋ฅผ ๊ฐœ๋ฐœํ•˜๋ฉฐ ๋งˆ์ฃผ์ณค๋˜ ๋ฌธ์ œ๋“ค์ด๋‚˜ ์–ด๋–ค์‹์œผ๋กœ ๊ฐœ๋ฐœ์„ ํ•˜์˜€๋Š”์ง€์— ๋Œ€ํ•ด ๊ธฐ์ˆ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์žฌ๋ฃŒ๋ช…์œผ๋กœ ๊ฒ€์ƒ‰ํ•˜๊ธฐ

์š”๋ฆฌ๋ณด๊ณ ๋Š” ํŠน์ • ์žฌ๋ฃŒ๋“ค์„ ๊ฐ€์ง€๊ณ  ์–ด๋–ค ์š”๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋ณด์—ฌ์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ ์‰ฝ๊ฒŒ ๋งํ•ด์„œ ๋ฐœํ™”๋ฅผ ํ†ตํ•ด ์ž…๋ ฅ๋œ ์žฌ๋ฃŒ๋“ค๋กœ ๊ฒ€์ƒ‰ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๋Œ€ํ‘œ๋ฐœํ™”

๋ฐœํ™” ์˜ˆ์‹œ

  1. "๋ผ์ง€๊ณ ๊ธฐ๋ž‘ ๊น€์น˜๋ž‘ ๋Œ€ํŒŒ ๋ ˆ์‹œํ”ผ ๋ณด์—ฌ์ค˜"
  2. "๊ฐ€์“ฐ์˜ค๋ถ€์‹œ๋ž‘ ์ฒญํฌ๋„๋ž‘ ๊ทค์ด๋ž‘ ๊ฐ•๋‚ญ์ฝฉ ํ•˜๋Š”๋ฒ• ์กฐํšŒํ•ด์ค˜"
  3. "๋ˆ„๋ฃฝ์ง€๋ž‘ ์‡ ๊ณ ๊ธฐ๋ž‘ ์–‘ํŒŒ ๋งŒ๋“œ๋Š” ๋ฒ• ๊ฒ€์ƒ‰ํ•ด"

์œ„์˜ ์„ธ๊ฐ€์ง€ ๋ฐœํ™”๋Š” ์ „๋ถ€ ๋‹ค๋ฅธ ๋ฐœํ™”์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์ผ์ •ํ•œ ํŒจํ„ด์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์žฌ๋ฃŒ๋ช…์œผ๋กœ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐœํ™”๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

ํŒจํ„ด - [์žฌ๋ฃŒ]๋ž‘ [์žฌ๋ฃŒ] [๋ ˆ์‹œํ”ผ] [๋ณด์—ฌ์ค˜]

**(๋ผ์ง€๊ณ ๊ธฐ)[v:Ingredient]**๋ž‘ **(๊น€์น˜)[v:Ingredeint]**๋ž‘ (๋Œ€ํŒŒ)[v:Ingredient] (๋ ˆ์‹œํ”ผ)[v:RecipeKeyword:๋ ˆ์‹œํ”ผ] (๋ณด์—ฌ์ค˜)[v:SearchKeyword:๊ฒ€์ƒ‰]

์š”๋ฆฌ๋ณด๊ณ ์—์„œ SearchKeyword์™€ RecipeKeyword๋ฅผ ๋”ฐ๋กœ enum ์œผ๋กœ ๋งŒ๋“ค์–ด ๋ฐœํ™”๋ฅผ ๊ตฌ์„ฑํ•œ ์ด์œ ๋Š” ์ค‘๋ณต๋ฐœํ™”๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค. "๋ณด์—ฌ์ค˜" , "์กฐํšŒํ•ด์ค˜" , "๊ฒ€์ƒ‰ํ•ด" ๋ฐœํ™”๋“ค์˜ ์˜๋ฏธ๋Š” ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ชจ๋‘ ๋˜‘๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋‚ด๋†“๋Š”๋ฐ ๊ตณ์ด ๊ฐ ๋‹จ์–ด์— ๋Œ€ํ•œ ๋ฐœํ™”๋ฅผ ์„ธ ๊ฐœ๋‚˜ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์žˆ์„๊นŒ์š”? ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ "ํ•˜๋Š”๋ฒ•", "๋งŒ๋“œ๋Š” ๋ฒ•" ๋ชจ๋‘ "๋ ˆ์‹œํ”ผ" ์™€ ์˜๋ฏธ๊ฐ€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ €ํฌ๋Š” ์ด๋Ÿฐ ๋ถ€๋ถ„์„ enum ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ vocab(...) ์— ์ •๋ฆฌ๋ฅผ ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด ํŒจํ„ด์€ ํ•˜๋‚˜์˜ ๋ฐœํ™”๋กœ ๋™์ผํ•œ ๋ฌธ์žฅ ๊ตฌ์กฐ ๋‚ด ์œ ์˜์–ด ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

๋ ˆ์‹œํ”ผ๋ช…์œผ๋กœ ๊ฒ€์ƒ‰ํ•˜๊ธฐ

์œ„์™€ ๋ฐ˜๋Œ€๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์žฌ๋ฃŒ๊ฐ€ ์•„๋‹Œ ์Œ์‹๋ช…์œผ๋กœ๋„ ๊ฒ€์ƒ‰์„ ์›ํ• ์ˆ˜๋„ ์žˆ๊ฒ ๋‹ค๋ผ๊ณ  ์ƒ๊ฐ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋ฉ”๋‰ด๋ช…์œผ๋กœ ๋ฐœํ™”ํ•˜์—ฌ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ๋„ ์ถ”๊ฐ€ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋Œ€ํ‘œ๋ฐœํ™”

๋ฐœํ™” ์˜ˆ์‹œ

  1. "์‚ผ๊ณ„ํƒ• ๋ ˆ์‹œํ”ผ ๊ฒ€์ƒ‰ํ•ด์ค˜"

ํŒจํ„ด - [๋ ˆ์‹œํ”ผ๋ช…] [์š”๋ฆฌ๋ฒ•] [๋ณด์—ฌ์ค˜]

[g:CommitRecipeSearch,r:BeginRecipeSearch] (์‚ผ๊ณ„ํƒ•)[v:RecipeName] (๋ ˆ์‹œํ”ผ)[v:RecipeKeyword:๋ ˆ์‹œํ”ผ] (๊ฒ€์ƒ‰ํ•ด์ค˜)[v:SearchKeyword:๊ฒ€์ƒ‰]

๋ ˆ์‹œํ”ผ๋ช… ๋ฐœํ™”๋„ ์žฌ๋ฃŒ๋ช…์œผ๋กœ ๊ฒ€์ƒ‰ํ•˜๊ธฐ์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ ์ž…๋ ฅ๋˜๋Š” ๋ชจ๋ธ์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๋ ˆ์‹œํ”ผ๋ช…์€ RecipeName ์œผ๋กœ ์ž…๋ ฅ๋˜๊ฒŒ ํ•˜์—ฌ ๊ตฌ๋ถ„ํ–ˆ๊ณ , ๋ ˆ์‹œํ”ผ์— ๊ด€๋ จ๋œ ๋ฐœํ™”๋“ค์„ ํ•˜๋‚˜์˜ ์•ก์…˜๊ณผ ํŠธ๋žœ์žญ์…˜์—์„œ ์ฒ˜๋ฆฌํ•˜์—ฌ ํ๋ฆ„์„ ๋‹จ์ˆœํ™” ์‹œ์ผฐ์Šต๋‹ˆ๋‹ค.

์นผ๋กœ๋ฆฌ๋กœ ๊ฒ€์ƒ‰ํ•˜๊ธฐ

์š”๋ฆฌ๋ณด๊ณ ๋Š” ๋‹ค๋ฅธ ์š”๋ฆฌ์•ฑ๊ณผ ๋‹ฌ๋ฆฌ ์„ ํƒ๋œ ์Œ์‹์˜ ์นผ๋กœ๋ฆฌ๋ฅผ ๋ชจ๋‘ ์†Œ๋ชจํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์šด๋™์„ ์–ผ๋งˆ๋‚˜ ํ•ด์•ผํ•˜๋Š”์ง€๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์„ ์กฐ๊ธˆ ๋” ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ  ์นผ๋กœ๋ฆฌ์— ๋งž๊ฒŒ ์š”๋ฆฌ๋ฅผ ํ•˜๊ณ  ์‹ถ์€ ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•ด ์นผ๋กœ๋ฆฌ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐœํ™”๋ฅผ ์ถ”๊ฐ€ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋Œ€ํ‘œ๋ฐœํ™”

"๋ ˆ์‹œํ”ผ" ๋Š” ์„ ํƒ์œผ๋กœํ•ด์„œ ๋ฐœํ™”ํ•  ๋•Œ ๋„ฃ์–ด๋„๋˜๊ณ  ์•ˆ ๋„ฃ์–ด๋„ ๋˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋ฐœํ™” ์˜ˆ์‹œ

  • "300 ์นผ๋กœ๋ฆฌ ์ด์ƒ 700 ์นผ๋กœ๋ฆฌ ๋ฏธ๋งŒ ๋ ˆ์‹œํ”ผ ์ฐพ์•„์ค˜"
  • "500 ์นผ๋กœ๋ฆฌ ์ด์ƒ ์š”๋ฆฌ๋ฒ• ๋ณด์—ฌ์ค˜"
  • "300 ์นผ๋กœ๋ฆฌ ๋ฏธ๋งŒ ์กฐํšŒํ•ด์ค˜"
  • "์นผ๋กœ๋ฆฌ 200์—์„œ 300์‚ฌ์ด ๋ณด์—ฌ์ค˜"

ํŒจํ„ด - [200] ์นผ๋กœ๋ฆฌ [์ด์ƒ] [300] ์นผ๋กœ๋ฆฌ [์ดํ•˜] {๋ ˆ์‹œํ”ผ} [๋ณด์—ฌ์ค˜]

[g:CommitRecipeSearch,r:WrapBoundaryOption,r:BeginRecipeSearch] (300)[v:LowerBound] ์นผ๋กœ๋ฆฌ (์ด์ƒ)[v:LowerBoundKeyword:์ด์ƒ] (700)[v:UpperBound] ์นผ๋กœ๋ฆฌ (๋ฏธ๋งŒ)[v:UpperBoundKeyword:์ดํ•˜] (๋ ˆ์‹œํ”ผ)[v:RecipeKeyword:๋ ˆ์‹œํ”ผ] (์ฐพ์•„์ค˜)[v:SearchKeyword:๊ฒ€์ƒ‰]

์นผ๋กœ๋ฆฌ ๊ฒ€์ƒ‰์€ ์ž…๋ ฅํŒจํ„ด์ด ๋‹ค์–‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด์ƒ/์ดํ•˜๊ฐ€ ์—†๋Š” ๋ฌธ์žฅ๋„ ๋ฐœํ™”๋กœ ๋„ฃ์–ด์„œ ๋‹ค์–‘ํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ปค๋ฒ„ํ•˜๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.

Issue

๋น…์Šค๋น„ ํ•™์Šต

์œ„์—์„œ ๊ฐ™์€ ๋ฌธ์žฅ๊ตฌ์กฐ ๋‚ด์˜ ์œ ์˜์–ด๋Š” enum ํƒ€์ž…์„ ํ†ตํ•ด ์ฒ˜๋ฆฌํ•œ๋‹ค๊ณ  ๋ง์”€๋“œ๋ ธ์Šต๋‹ˆ๋‹ค๋งŒ, ๊ฐ ๋‹จ์–ด๋ฅผ ํ•œ ๋ฒˆ์”ฉ์€ ๋ฐœํ™”๋กœ ํŠธ๋ ˆ์ด๋‹์„ ์‹œ์ผœ์ฃผ์–ด์•ผ๋งŒ ๋น…์Šค๋น„๊ฐ€ ์ธ์‹ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด์„œ ์ž์„ธํ•˜๊ฒŒ ๋ง์”€๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

์˜ˆ์‹œ

  • ์‡ ๊ณ ๊ธฐ๋ž‘ ๋ฏธ์—ญ ๋ ˆ์‹œํ”ผ ๋ณด์—ฌ์ค˜

    • ์‡ ๊ณ ๊ธฐ๋ž‘ ๋ฏธ์—ญ ์š”๋ฆฌ๋ฒ• ์•Œ๋ ค์ค˜

    • ์‡ ๊ณ ๊ธฐ๋ž‘ ๋ฏธ์—ญ ๋งŒ๋“œ๋Š” ๋ฒ• ๊ฐ€๋ฅด์ณ์ค˜

์œ„์—์„œ "์‡ ๊ณ ๊ธฐ๋ž‘ ๋ฏธ์—ญ ๋ ˆ์‹œํ”ผ ๋ณด์—ฌ์ค˜" ์˜ ๋ฐœํ™” ๊ฒฐ๊ณผ์™€ 1, 2๋ฒˆ์˜ ๋ฐœํ™” ๊ฒฐ๊ณผ๊ฐ€ ๊ฐ™๊ณ  ๋™์ ์œผ๋กœ ๋ณ€ํ•˜๋Š” ๊ฐ’์€ "์‡ ๊ณ ๊ธฐ" ๋ž‘ "๋ฏธ์—ญ" ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿด๊ฒฝ์šฐ "๋ ˆ์‹œํ”ผ", "๋ณด์—ฌ์ค˜" ๋ฅผ enum ํƒ€์ž…์œผ๋กœ ์„ ์–ธํ•˜์—ฌ ๋น„์Šทํ•œ ๋™์˜์–ด๋ฅผ voca ์— ์ •์˜ํ•˜๋ฉด ๋™์˜์–ด ์ˆ˜๋งŒํผ ๋ฐœํ™”๋ฅผ ์ถ”๊ฐ€ํ•  ํ•„์š”๊ฐ€ ์—†์ง€๋งŒ ํ•œ ๋ฒˆ์€ ์ž…๋ ฅ์„ ํ•ด์ฃผ์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ ์œ„์˜ ์„ธ ๊ฐœ์˜ ๋ฐœํ™”์— ๋Œ€ํ•ด ํ•™์Šต์ด ๋˜์–ด์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด "์‡ ๊ณ ๊ธฐ๋ž‘ ๋ฏธ์—ญ ๋ ˆ์‹œํ”ผ ๋ณด์—ฌ์ค˜" ํ˜•ํƒœ๋Š” ์œ ์ง€ํ•˜๋˜ "์‡ ๊ณ ๊ธฐ", "๋ฏธ์—ญ" ๋ถ€๋ถ„์€ ์–ด๋–ค ์žฌ๋ฃŒ๊ฐ€ ๋˜๋“  ์ƒ๊ด€์—†๊ณ  ๋ฐ”๋€ ์žฌ๋ฃŒ์— "์š”๋ฆฌ๋ฒ• ์•Œ๋ ค์ค˜", "๋งŒ๋“œ๋Š” ๋ฒ• ๊ฐ€๋ฅด์ณ์ค˜" ๋กœ ๊ตฌ์„ฑ๋œ ๋ฐœํ™”๋Š” ๊ตณ์ด ์ถ”๊ฐ€์•ˆํ•ด๋„ ๋น…์Šค๋น„๊ฐ€ ํ•™์Šตํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋™์˜์–ด๋กœ "์กฐ๋ฆฌ๊ณผ์ • ์กฐํšŒํ•ด์ค˜" ์˜ ๊ฒฝ์šฐ์—๋Š” ์•„์ง ํ•™์Šต์„ ๋ชปํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— voca ์— ์žˆ๋‹ค๊ณ  ํ•ด๋„ ๋น…์Šค๋น„๊ฐ€ ์ดํ•ด๋ชปํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ฒฐ๋ก ์€ ๋™์ ์œผ๋กœ ๋ฐ”๋€Œ๋Š” ๋ถ€๋ถ„์€ ์ œ์™ธํ•˜๊ณ  ์ •์ ์ธ ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ๋Š” enum ์„ ํ†ตํ•ด ๋™์˜์–ด๋ฅผ voca ์— ์ •์˜ํ•œ ํ›„ ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๋™์˜์–ด์— ๋Œ€ํ•ด ํ•œ ๋ฒˆ์”ฉ์€ ๋น…์Šค๋น„์—๊ฒŒ ๊ฐ€๋ฅด์ณ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ˆซ์ž์™€ ๋ฌธ์ž ์ธ์‹

์บก์А ๊ฐœ๋ฐœ์„ ํ•˜๋ฉด์„œ ๋น…์Šค๋น„๊ฐ€ ๊ฐ€๋”์”ฉ ๋ฌธ์ž์™€ ์ˆซ์ž๋ฅผ ํ˜ผ๋™ํ•˜์—ฌ ์ธ์‹ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค. ํ•œ๊ฐ€์ง€ ์˜ˆ๊ฐ€ ๋ฐ”๋กœ "์˜ค์ด" ๋ผ๋Š” ๋‹จ์–ด์ธ๋ฐ์š”. ์ž๊พธ ๋น…์Šค๋น„๊ฐ€ "์˜ค2" ๋ผ๊ณ  ์ธ์‹ํ•˜๋Š” ๋ฐ”๋žŒ์— ์กฐ๊ธˆ ๋‚œ๊ฐํ–ˆ๋˜ ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿด ๋•Œ๋Š” ๋ฐœํ™”๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ "์˜ค์ด" ๋ผ๋Š” ๋‹จ์–ด๋ฅผ ๊ผญ ๋„ฃ์–ด์„œ ํ•™์Šต์„ ์‹œ์ผฐ๋”๋‹ˆ ์ธ์‹๋ฅ ์ด ๋งŽ์ด ์˜ฌ๋ผ๊ฐ”์Šต๋‹ˆ๋‹ค.

๊ตฌ๋ถ„์ž

๋ฐœํ™”๋ฅผ ํŠธ๋ ˆ์ด๋‹ ํ•˜๋‹ค๊ฐ€ ๋ณด๋ฉด ๋น…์Šค๋น„ ํ•™์Šต ํŒจํ„ด์„ ์•Œ ์ˆ˜ ์žˆ๋Š”๋ฐ, ํ•™์Šตํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํ† ๋Œ€๋กœ ๊ตฌ๋ถ„์ž๋ฅผ ํ†ตํ•ด ๋ฌธ์žฅ์—์„œ ํ•„์š”ํ•œ ๋‹จ์–ด๋งŒ ์ถ”์ถœ์„ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋กœ๋“ค์–ด์„œ, "ํ”ผ๋ง์ด๋ž‘ ๋ฒ„์„ฏ์ด๋ž‘ ์–‘ํŒŒ ๋ ˆ์‹œํ”ผ ์•Œ๋ ค์ค˜" ๋ผ๋Š” ๋ฐœํ™”๋ฅผ ํ•™์Šต ์‹œ์ผฐ์„ ๋•Œ ๋น…์Šค๋น„๋Š” "์ด๋ž‘" ์ด๋ผ๋Š” ๋‹จ์–ด๋ฅผ ๊ตฌ๋ถ„์ž๋กœ ์ถ”๊ฐ€๋ฅผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ๋‹ค์Œ "์˜ค์ด๋ž‘ ๋Œ€ํŒŒ ๋ ˆ์‹œํ”ผ ์•Œ๋ ค์ค˜" ๋ผ๊ณ  ํ–ˆ์„ ๋•Œ "์˜ค์ด", ***"๋Œ€ํŒŒ"***๋ฅผ ์ถ”์ถœ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ "์˜ค", ***"๋Œ€ํŒŒ"***๋ฅผ ์ถ”์ถœํ•˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•˜์—ฌ์„œ ํ˜ผ๋™์ด ์˜ฌ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์žฅ๋“ค์— ๋Œ€ํ•ด ๊ผญ ํŠธ๋ ˆ์ด๋‹์„ ํ•˜์‹œ๊ณ  ๋‹ค์–‘ํ•œ ํŒจํ„ด์˜ ๋ฐœํ™”๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

ํŠธ๋žœ์žญ์…˜

๋ณดํ†ต ๊ฒ€์ƒ‰์€ ํŠธ๋žœ์žญ์…˜ ํƒ€์ž…์ด ์•„๋‹Œ ๊ฒ€์ƒ‰ ํƒ€์ž…์œผ๋กœ ๊ตฌํ˜„ํ•˜์ง€๋งŒ, ์š”๋ฆฌ๋ณด๊ณ ์—์„œ๋Š” ๋ ˆ์‹œํ”ผ ๊ฒ€์ƒ‰ ๋„์ค‘ ์ด์ „ ์ƒํƒœ๋ฅผ ํ•จ๊ป˜ ํ™œ์šฉํ•˜์—ฌ ํ˜„์žฌ ์ž…๋ ฅ๋œ ๋ฐœํ™”(๋ช…๋ น)๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ์œ„ํ•ด ํŠธ๋žœ์žญ์…˜์„ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์žฌ๋ฃŒ๋ช…์„ ์ด์šฉํ•œ ๋ ˆ์‹œํ”ผ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ์—์„œ ๊ฒ€์ƒ‰ ์กฐ๊ฑด์œผ๋กœ ์žฌ๋ฃŒ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•  ๋•Œ์™€ ์„ ํƒ๋œ ๋ ˆ์‹œํ”ผ์— ๋Œ€ํ•œ ์š”๋ฆฌ๊ณผ์ • ํ™”๋ฉด ์ถœ๋ ฅ ๊ธฐ๋Šฅ์—์„œ ๊ฐ ์š”๋ฆฌ๊ณผ์ •์„ ๋‹จ๊ณ„์ ์œผ๋กœ ๋ณด์—ฌ์ค„๋•Œ ํ™œ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋ ˆ์‹œํ”ผ ๊ฒ€์ƒ‰

๊ด€๋ จ ํŒŒ์ผ

  • actions/recipe : BeginRecipeSearch.model.bxb, CommitRecipeSearch.model.bxb, UpdateRecipeSearch.model.bxb, SelectRecipeSearch.model.bxb
  • concepts/commit : RecipeCommitState.model.bxb
  • views/recipe : RecipeConfirmation.view.bxb, RecipeList.view.bxb

์„ค๋ช…

์‚ฌ์šฉ์ž ์ž…๋ ฅ ๋ฐœํ™”๊ฐ€ ๋“ค์–ด์™”์„ ๋•Œ ๋ ˆ์‹œํ”ผ ๊ฒ€์ƒ‰ ํŠธ๋žœ์žญ์…˜ ์ „์ฒดํ๋ฆ„์ž…๋‹ˆ๋‹ค. 4. ๋ฐœํ™”์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ์š”๋ฆฌ๋ณด๊ณ ์—๋Š” ๋ ˆ์‹œํ”ผ ๊ฒ€์ƒ‰์— ๋Œ€ํ•ด ์ด 3์ข…๋ฅ˜์˜ ๋ฐœํ™”( ์žฌ๋ฃŒ๋ช…์„ ์ด์šฉํ•œ ๋ ˆ์‹œํ”ผ ๊ฒ€์ƒ‰ , ๋ ˆ์‹œํ”ผ๋ช…์„ ์ด์šฉํ•œ ๋ ˆ์‹œํ”ผ ๊ฒ€์ƒ‰ , ์นผ๋กœ๋ฆฌ๋ฅผ ์ด์šฉํ•œ ๋ ˆ์‹œํ”ผ ๊ฒ€์ƒ‰ ) ๊ฐ€ ์กด์žฌํ•˜๋ฉฐ, ์ด ๋ฐœํ™”๋“ค์€ ๊ณตํ†ต์ ์œผ๋กœ ์•„๋ž˜์˜ ํ๋ฆ„์„ ๋”ฐ๋ผ๊ฐ‘๋‹ˆ๋‹ค.

๋ฐœํ™”๋Š” BeginRecipeSearch์„ ๊ฑฐ์ณ์„œ CommitRecipeSearch๋กœ ๊ฐ€๊ฒŒ ๋˜๋Š”๋ฐ, ๋ ˆ์‹œํ”ผ ๊ฒ€์ƒ‰ ํŠธ๋žœ์žญ์…˜ ์ „์ฒด๋ฅผ ์˜๋ฏธํ•˜๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์ตœ์ข… ๋ ˆ์‹œํ”ผ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•˜๊ธฐ ์ „๊นŒ์ง€ ์ข…๋ฃŒ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. UpdateRecipeSearch๋Š” ํŠธ๋žœ์žญ์…˜ ๋„์ค‘ ์กฐ๊ฑด์„ ๋‹ค๋ฅด๊ฒŒ ํ•˜์—ฌ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉ๋˜๋Š”๋ฐ ํ˜„์žฌ๋Š” ์žฌ๋ฃŒ๋ช…์„ ์ด์šฉํ•œ ๋ ˆ์‹œํ”ผ ๊ฒ€์ƒ‰์—์„œ ์žฌ๋ฃŒ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐ ํ•˜๋Š”๋ฐ ์ฃผ๋กœ ํ™œ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ์˜ˆ์‹œ ๋ฐœํ™”์ž…๋‹ˆ๋‹ค.

  1. "์–‘ํŒŒ๋ž‘ ๋ผ์ง€๊ณ ๊ธฐ๋ฅผ ์ด์šฉํ•œ ์š”๋ฆฌ๋ฒ• ๊ฒ€์ƒ‰ํ•ด์ค˜"
  2. "์–‘ํŒŒ ๋นผ๊ณ  ๊ฒ€์ƒ‰ํ•ด์ค˜"
  3. "๊น€์น˜ ์ถ”๊ฐ€ํ•ด์„œ ๊ฒ€์ƒ‰ํ•ด์ค˜"

SelectRecipeSearch๋Š” ๊ฒ€์ƒ‰๋œ ๋ ˆ์‹œํ”ผ ์ค‘ ํ•˜๋‚˜์— ๋Œ€ํ•œ ์ƒ์„ธ์ •๋ณด๋ฅผ ๋ณด๊ณ ์‹ถ์„ ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋ ˆ์‹œํ”ผ ๊ฒ€์ƒ‰ ํŠธ๋žœ์žญ์…˜ ์ „๋ฐ˜์— ๊ฑธ์ณ ์œ ์ง€๋˜๋Š” RecipeCommitState๋Š” ํ˜„์žฌ ๊ฒ€์ƒ‰ ์กฐ๊ฑด ์ƒํƒœ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ตฌ์กฐ์ฒด๋กœ, ๋ฐœํ™” ์‚ฌ์ด์— ๋ฌธ๋งฅ์„ ๋งŒ๋“ค์–ด ์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. RecipCommitState๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ๋ฆ„์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

์œ„ ๊ทธ๋ฆผ์—์„œ RecipeCommitState๋Š” BeginRecipeSearch์—์„œ ์ƒ์„ฑ๋˜์–ด CommitRecipeSearch - UpdateRecipeSearch ์‚ฌ์ดํด์— ์ฃผ์ž…๋œ ํ›„, ํ•˜๋‚˜์˜ CommitRecipeSearch๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ์œ ์ง€๋˜๋ฉฐ ์ž…๋ ฅ๋œ ์‚ฌ์šฉ์ž์˜ ๋ฐœํ™”์— ๋”ฐ๋ผ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์š”๋ฆฌ๊ณผ์ • ๋ณด๊ธฐ

๊ด€๋ จ ํŒŒ์ผ

  • actions/process : BeginProcessShow.model.bxb, CommitRecipeShow.model.bxb, UpdateRecipeShow.model.bxb
  • concepts/commit : ProcessCommitState.model.bxb
  • views/process : ProcessConfirmation.view.bxb

์„ค๋ช…

์•„๋ž˜์˜ ๊ทธ๋ฆผ์€ ์‚ฌ์šฉ์ž๊ฐ€ ๋ ˆ์‹œํ”ผ ๊ฒ€์ƒ‰์„ ํ†ตํ•ด ์ตœ์ข…์ ์œผ๋กœ ์š”๋ฆฌ๋ฅผ ์„ ํƒํ–ˆ์„ ๋•Œ, ํ•ด๋‹น ์š”๋ฆฌ์— ๋Œ€ํ•œ ์š”๋ฆฌ๊ณผ์ •์„ ๋ณด๊ธฐ ์œ„ํ•œ ํŠธ๋žœ์žญ์…˜ ์ „์ฒดํ๋ฆ„์ž…๋‹ˆ๋‹ค.

๋ ˆ์‹œํ”ผ ๊ฒ€์ƒ‰๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ CommitProcessSearch๋Š” ์š”๋ฆฌ๊ณผ์ • ๋ณด๊ธฐ์— ๋Œ€ํ•œ ํŠธ๋žœ์žญ์…˜ ์ž์ฒด๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. UpdateProcessSearch๋Š” ์š”๋ฆฌ๊ณผ์ •์„ ๋‹จ๊ณ„์ ์œผ๋กœ ๋ณด์—ฌ์ค„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์‚ฌ์šฉ์ž๋Š” "๋‹ค์Œ" ํ˜น์€ "์ด์ „" ๋ฐœํ™”๋ฅผ ์ด์šฉํ•˜์—ฌ ์ด์ „ ๋‹จ๊ณ„ ํ˜น์€ ๋‹ค์Œ ๋‹จ๊ณ„์˜ ์š”๋ฆฌ๊ณผ์ •์œผ๋กœ ๋„˜์–ด๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ ˆ์‹œํ”ผ ๊ฒ€์ƒ‰ ํŠธ๋žœ์žญ์…˜๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์š”๋ฆฌ๊ณผ์ • ํŠธ๋žœ์žญ์…˜์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” ProcessCommitState๊ฐ€ ์œ ์ง€๋˜๋ฉฐ, ์ด ๊ตฌ์กฐ์ฒด๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์˜ ๋ฐœํ™”(๋ช…๋ น)์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์—๋Ÿฌ์ฒ˜๋ฆฌ

๋น…์Šค๋น„ ๋™์ž‘์—์„œ ํ•„์š”ํ•œ ๋ถ€๋ถ„์€ ํฌ๊ฒŒ 3๊ฐ€์ง€๋กœ Concept, Action, Code(Javascript) ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋ช…๋ น์„ ์ •์˜ํ•˜๊ณ  ์ˆ˜ํ–‰ํ•˜๋Š” ๋ถ€๋ถ„์€ Action๊ณผ Code์ด๊ธฐ ๋•Œ๋ฌธ์— ์—๋Ÿฌ๋„ ์ด 2๊ณณ์—์„œ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ ํ•„์š”ํ•œ ๋ช…๋ น์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ถ€๋ถ„์ธ Code์—์„œ ์—๋Ÿฌ๋ฅผ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ ์œผ๋กœ ๋ฐœ์ƒ์‹œํ‚ค๊ณ , Action์—์„œ๋Š” ๋ฐœ์ƒ๋œ ์—๋Ÿฌ ์ข…๋ฅ˜์— ๋”ฐ๋ผ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

๊ด€๋ จ ํŒŒ์ผ

  • actions/recipe : BeginRecipeSearch.model.bxb
  • code/recipe : BeginRecipeSearch.js

BeginRecipeSearch.js

var fail = require('fail');

if(db == undefined || db.length == 0){
    // ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๋ถ€๋ถ„
    throw fail.checkedError('There is no process', 'NotFoundRecipes', null);
}

BeginRecipeSearch.bxb

//๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋Š” action์˜ output์—์„œ ์ฒ˜๋ฆฌํ•œ๋‹ค.
output (RecipeCommitState){
    throws{
        //BeginRecipeSearch.js์—์„œ throw๋ฅผ ํ†ตํ•ด ๋˜์งˆ ๋•Œ ์ •์˜ํ•œ ์ด๋ฆ„
        error (NotFoundRecipes){
            on-catch{
                // ์บก์А ๋™์ž‘์„ ์ •์ง€ํ•จ
                halt{
                    // ์ƒ๋‹จ์— ๋…ธ์ถœ๋˜๋Š” ๋ฉ”์‹œ์ง€
                    dialog("๋ ˆ์‹œํ”ผ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
                }
            }
        }
        //๊ทธ ์™ธ ์—๋Ÿฌ
        unknown-error{
            on-catch{
                halt{
                    dialog("์˜ˆ๊ธฐ์น˜ ๋ชปํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.")
                }
            }
        }
    }
}

์ฐธ๊ณ ์ž๋ฃŒ

HTTP ์š”์ฒญ

๋น…์Šค๋น„์—์„œ Http Request๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์บก์А์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๊ด€๋ จ ํŒŒ์ผ

  • code/lib : tool.js

tool.js

module.exports.searchRecipeByName = function(recipeName){
  let queryName = recipeName.replace(' ', '');
  // ์ „์†ก์— ํ•„์š”ํ•œ ์„ค์ •, ํŒŒ๋ผ๋ฉ”ํ„ฐ๋“ค์„ ์œ„ํ•œ ๊ฐ์ฒด
  let options = {
    //ํŒŒ๋ผ๋ฉ”ํ„ฐ
    query : {
      recipeName : queryName
    },
    format : "json"
  };
  return http.getUrl(config.get('remote.url') + 'foodBasic/searchByRecipeName', options);
}

์ฐธ๊ณ ์ž๋ฃŒ

์™ธ๋ถ€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰

๋น…์Šค๋น„์—์„œ ์™ธ๋ถ€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ˜ธ์ถœํ•˜๋ ค๋ฉด App launch๋ฅผ ํ˜ธ์ถœํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. App launch๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ˜ธ์ถœํ•˜๋ฉด์„œ ๋น…์Šค๋น„๋ฅผ ์ข…๋ฃŒํ•˜๋Š”๋ฐ, ์ด๋Š” ํ˜„์žฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ ์œผ๋กœ ๋น…์Šค๋น„๋ฅผ ์ข…๋ฃŒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์š”๋ฆฌ๋ณด๊ณ ์—์„œ๋Š” App launch๋ฅผ ์ด์šฉํ•˜์—ฌ ์„ ํƒ๋œ ๋ ˆ์‹œํ”ผ์— ๋Œ€ํ•œ ์œ ํŠœ๋ธŒ ๋™์˜์ƒ์„ ๋ธŒ๋ผ์šฐ์ €๋กœ ๋„์›Œ์ฃผ๋Š” ๊ธฐ๋Šฅ์ด ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋™์˜์ƒ URL์€ Youtube API๋ฅผ ์ด์šฉํ•˜์˜€์œผ๋‹ˆ API์— ๋Œ€ํ•œ ์‚ฌ์šฉ๋ฐฉ๋ฒ•์€ ์ด๊ณณ์„ ์ฐธ๊ณ ํ•ด์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ด€๋ จ ํŒŒ์ผ

  • actions/process : CommitProcessShow.model.bxb
  • concepts/api : YoutubeResult.model.bxb
  • views : UrlLauncher.view.bxb

UrlLauncher.bxb

//ResultView์—์„œ ์‚ฌ์šฉ  
app-launch{
  //์—ฐ๊ฒฐํ•˜๊ณ ์ž ํ•˜๋Š” ๋ธŒ๋ผ์šฐ์ € URL
  payload-uri("#{value(this.url)}")
}

์ฐธ๊ณ ์ž๋ฃŒ

๋ถ€๋ก

Youtube API

์ธ์ฝ”๋”ฉ๋œ ๊ฒ€์ƒ‰์–ด๋ฅผ parameter๋กœ ๋„ฃ์–ด Youtube ์„œ๋ฒ„๋กœ ์ „์†ก์„ ํ•˜๋ฉด JSON ํ˜•ํƒœ๋กœ ๊ฒ€์ƒ‰๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” API ์ž…๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜๋˜๋Š” ๊ฒฐ๊ณผ์—๋Š” thumbnail ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋™์˜์ƒ์— ๋Œ€ํ•œ ์„ค๋ช… ๋“ฑ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ์ถ”์ถœํ•˜์—ฌ์„œ ์‚ฌ์šฉํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Youtube Search API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.


  1. API Key๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‹จ์ˆœ ๊ฒ€์ƒ‰
  2. OAuth ์ธ์ฆ์„ ํ†ตํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

์ด๋ ‡๊ฒŒ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”๋ฐ, OAuth ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” Google ๋กœ๊ทธ์ธ๊ณผ ๊ฐ™์€ ์จ๋“œ ํŒŒํ‹ฐ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•œ ์ ์ด ์žˆ์ง€๋งŒ ์ €ํฌ ์บก์А์—์„œ๋Š” ๋กœ๊ทธ์ธ์ด๋‚˜ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— API Key๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ฟผ๋ฆฌ๋ฅผ ์ „์†กํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›๋Š” ํ˜•์‹์œผ๋กœ ๊ฐœ๋ฐœ์„ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

JAVA ์˜ˆ์ œ

์•„๋ž˜์— ๋ณด์‹œ๋ฉด URL ์ฃผ์†Œ๊ฐ€ ์žˆ๋Š”๋ฐ ๋“ค์–ด๊ฐ€๋ณด์‹œ๋ฉด, ์˜ˆ์ œ๋“ค์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ JAVA์–ธ์–ด๋กœ ์ž‘์„ฑ๋œ sample code๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ์ฝ”๋“œ์˜ ํ•ต์‹ฌ์ ์ธ ๋ถ€๋ถ„๋งŒ ์„ค๋ช…์„ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

API Key
/** Global instance properties filename. */
private static String PROPERTIES_FILENAME = "youtube.properties";

// youtube.properties
# Replace this with an API key available at
# https://console.developers.google.com/project/_/apiui/credential
youtube.apikey=๊ฐ’์„ ์ž…๋ ฅํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์œ„์˜ ์ฝ”๋“œ๋Š” Google Cloud Platform์—์„œ ๋ฐœ๊ธ‰๋ฐ›์€ API Key๋ฅผ youtube.properties ํŒŒ์ผ์— ๋„ฃ์–ด์คŒ์œผ๋กœ์จ ์‚ฌ์šฉํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธ์ฆ๋œ ๊ฐ’์„ ์ •ํ™•ํ•˜๊ฒŒ ์ž…๋ ฅํ•˜๊ฒŒ ๋˜๋ฉด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Part
YouTube.Search.List search = youtube.search().list("id,snippet");

Youtube API์— ์ฟผ๋ฆฌ๋ฅผ ๋ณด๋‚ผ๋•Œ ํ•„์ˆ˜์ ์œผ๋กœ ํฌํ•จ๋˜์–ด์•ผ ํ•˜๋Š” parameter๊ฐ€ ์žˆ๋Š”๋ฐ ๋ฐ”๋กœ Part ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๊ณต์‹๋ฌธ์„œ์—์„œ๋„ Part๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ๋ถ€๋ถ„์€ ์„ ํƒ์ธ ๊ฒƒ์— ๋ฐ˜ํ•ด Part ๋ถ€๋ถ„์€ ํ•„์ˆ˜์˜์—ญ์œผ๋กœ ์ง€์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์œ„์˜ code๋ฅผ ๋ณด์‹œ๋ฉด id, snippet ์ด๋ผ๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ๋Š”๋ฐ, Part ์— id๋งŒ ์ฃผ๊ฒŒ๋˜๋ฉด videoId, etag ์™€ ๊ฐ™์€ key ๊ฐ’ ์ •๋„๋งŒ ๋ฐ›์•„๋ณด์‹ค ์ˆ˜ ์žˆ๊ณ , Part์— snippet์„ ์ฃผ๊ฒŒ๋˜๋ฉด videoId ๋ฅผ ํฌํ•จํ•œ title, description ๊ณผ ๊ฐ™์€ ๋™์˜์ƒ์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ •๋ณด๋“ค์„ JSON ํ˜•์‹์œผ๋กœ ๋ฐ›์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ’ ์ถ”์ถœ
private static void prettyPrint(Iterator<SearchResult> iteratorSearchResults, String query) {

    //๋ถˆํ•„์š”ํ•œ ์ถœ๋ ฅ๋ฌธ ์ƒ๋žต
    .....

        if (!iteratorSearchResults.hasNext()) {
            System.out.println(" There aren't any results for your query.");
        }

    while (iteratorSearchResults.hasNext()) {

        SearchResult singleVideo = iteratorSearchResults.next();
        ResourceId rId = singleVideo.getId();

        // Double checks the kind is video.
        if (rId.getKind().equals("youtube#video")) {
            Thumbnail thumbnail = singleVideo.getSnippet().getThumbnails().get("default");

            System.out.println(" Video Id" + rId.getVideoId());
            System.out.println(" Title: " + singleVideo.getSnippet().getTitle());
            System.out.println(" Thumbnail: " + thumbnail.getUrl());
            ...
        }
    }
}

์œ„์—์„œ properties์— ์ ์ ˆํ•œ key ๊ฐ’์„ ๋„ฃ์—ˆ๋‹ค๋ฉด ๊ธฐ๋ณธ๊ฐ’์ธ YouTube Developers Live์˜ ๊ฒ€์ƒ‰๊ฒฐ๊ณผ๊ฐ€ ๋ฐ˜ํ™˜๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด์„œ๋Š” ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ์š”? ์œ„์— prettyPrint method์˜ parameter๋ฅผ ์‚ดํŽด๋ณด๋ฉด iteratorSearchResults๋ฅผ ํ†ตํ•ด ๊ฒ€์ƒ‰๊ฒฐ๊ณผ๋ฅผ iterator ํ˜•์‹์œผ๋กœ ๋ฐ›์•„๋ณผ ์ˆ˜ ์žˆ๊ณ  key๋“ค์ด ๋ชจ๋‘ get method๊ฐ€ ๋งŒ๋“ค์–ด์ ธ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์•„์ฃผ ํŽธํ•˜๊ฒŒ ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ  ์ž๋ฃŒ

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors