"์๋ ํ์ธ์. ๊ฐ๋ฐ์์๊ฒ ์ฆ๊ฑฐ์์, ์ฌ์ฉ์์๊ฒ ํธ๋ฆฌํจ์ ์ ๋ฌผํ๋ ์๋ฆฌ๋ณด๊ณ ํ์ ๋๋ค."
- ์บก์๊ตฌ์กฐ
- ์บก์์ค์
- ์ฌ์ (Dictionary)
- ๋ฐํ(Training)
- ํธ๋์ญ์
- ๋ ์ด์์
- ์๋ฌ์ฒ๋ฆฌ
- HTTP ์์ฒญ
- ์ธ๋ถ ์ดํ๋ฆฌ์ผ์ด์ ์คํ
- ๋ถ๋ก
์บก์์ ํฌ๊ฒ assets, code, models, resources ๋ถ๋ถ์ผ๋ก ๋๋์ ธ ์๋๋ฐ assets ๊ฐ์ ๊ฒฝ์ฐ์๋ ์ ์ ์ผ๋ก ์ฌ์ฉ๋๋ ํ์ผ(์ด๋ฏธ์ง)์ด ์ ์ฅ๋์ด์๊ณ , code ๋ถ๋ถ์ .js ํ์ผ๋ค์ ๊ฐ ๊ธฐ๋ฅ์ ๋ง๊ฒ ํด๋๋ฅผ ๋ง๋ค์ด์ ๊ตฌ์ฑ์ ํ์์ต๋๋ค. ์ด๋ฏธ์ง ํ์ผ๋ง ์๋ assets๊ณผ .js ํ์ผ์ด ์๋ code์ ์ ์ธํ๊ณ ๋๋จธ์ง ํด๋๋ค์ ๊ตฌ์กฐ์ ๋ํด์ ์ค๋ช ์ ๋๋ฆฌ๊ฒ ์ต๋๋ค.
๋๋ ํ ๋ฆฌ ์์ธ
- 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 ๋ผ๋ ํด๋๋ฅผ ๋ง๋ค์ด์ ํด๋น ํด๋ ์์ ์์ฑ์ ํ์ฌ ๊ด๋ฆฌ๋ฅผ ์ฉ์ดํ๊ฒ ํ์์ต๋๋ค.
๋๋ ํ ๋ฆฌ ์์ธ
- 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 ํค๊ฐ์ด๋ ๊ถํ ๋ฒ์ ๋ฑ ์บก์์ ๊ตฌ์ฑํ ๋ ํ์ํ ๊ฐ๋ค์ ์ ์ฅํ ์ ์์ต๋๋ค. ์ด์ธ์ ํ์ผ๋ค์ ๋ํด์๋ ์บก์์ค์ ๋ถ๋ถ์์ ๋ค์ ์ธ๊ธํ๋๋ก ํ๊ฒ ์ต๋๋ค.
๋น ์ค๋น ์บก์์ ๊ฐ๋ฐํ๋ฉด์ ํ์ํ๊ฑฐ๋ ๋์์ด ๋๋ ์ค์ ๋ค์ ๋ํด์ ๋ง์๋๋ฆฌ๊ฒ ์ต๋๋ค.
uncategorized{
utterance (์ฌ์ฉ๋ฒ ๊ฐ๋ฅด์ณ์ค)
utterance (๋ฏธ์ญ์ด๋ ์ ๊ณ ๊ธฐ ์๋ฆฌ๋ฒ ์ฐพ์์ค)
utterance (๋ณด์๊น์น ๋ ์ํผ ๋ณด์ฌ์ค)
utterance (300์นผ๋ก๋ฆฌ ์ด์ ๋ ์ํผ ๋ณด์ฌ์ค)
}hints.bxb ํ์ผ ๊ฐ์ ๊ฒฝ์ฐ์๋ ์บก์์ด ์ค์ ๋ง์ผ ํ๋ ์ด์ค์ ์
๋ก๋ ๋์์ ๋ ์ฌ์ฉ์๋ค์๊ฒ ๋ํ๋ฐํ ์์ ๋ก ๋ณด์ฌ์ค ๋ฐํ ๋ฆฌ์คํธ์
๋๋ค. (์ ์ผ ๋จผ์ ์ฌ์ฉํ ์ ์๋ ๋ฐํ๋ค์ด๊ธฐ ๋๋ฌธ์ ์ถฉ๋ถํ ํ
์คํธ๋ฅผ ๊ฑฐ์ณ์ผํฉ๋๋ค.) ์์ ๊ฐ์ด ์
๋ ฅํ ํ ์บก์์ด ๋ง์ผ ํ๋ ์ด์ค์ ๋ฑ๋ก ๋๋ค๋ฉด ์๋์ ๊ฐ์ด ํ์ธ ํ์ค ์ ์์ต๋๋ค.
utterance(...) ์์ ๋ฃ์ ๋ฐํ ์์ "์๋ฆฌ๋ณด๊ณ ์์, " ๋ผ๋ ๋ฌธ์ฅ์ด ๋ค์ด๊ฐ ๊ฒ์ ๋ณด์ค ์ ์๋๋ฐ, ํด๋น ๋ถ๋ถ์ ์บก์ ์ด๋ฆ์ผ๋ก capsule.bxb ์ ์
๋ ฅํ ๋ณ์นญ์ ๋ฐ๋ผ ์๋์ ์ผ๋ก ๋ค์ด๊ฐ๊ฒ ๋ฉ๋๋ค.
capsule-info {
display-name (์๋ฆฌ๋ณด๊ณ )
...
dispatch-aliases{
alias (์๋ฆฌ ๋ณด๊ณ )
}
...capsule-info.bxb ํ์ผ์ ์บก์์ ๋ณ์นญ์ dispatch-aliases{...} ์ ์
๋ ฅํ์ฌ ์ ํ ์ ์์ต๋๋ค. ์ ํฌ ์บก์ ๊ฐ์ ๊ฒฝ์ฐ์๋ ์๋ฆฌ ๋ณด๊ณ ์ธ๋ฐ, ๋ฐ์ํ๊ธฐ ์ด๋ ค์ด ๋จ์ด๋ค์ ๋น
์ค๋น๊ฐ ์ธ์ํ๊ธฐ ์ด๋ ต๊ธฐ ๋๋ฌธ์ ๋๋๋ก์ด๋ฉด ์ฝ๊ณ ๊ฐ๋จํ ๋ณ์นญ์ ๊ถ์ฅํฉ๋๋ค.
์บก์ ๊ฐ๋ฐ ๋์ค 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 {
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 ๋ถ๋ถ์ ๊ฐ๋ฐ ์ค์ธ ์บก์์ ์นดํ
๊ณ ๋ฆฌ์ ๋ง๊ฒ ์ ํํ์๋ฉด ๋๋๋ฐ ์ข
๋ฅ๋ ์๋์ ๊ฐ์ต๋๋ค.
์์ ์น์ ์ข ๋ฅ
ArtAndLifestyleBusinessAndFinanceCommunicationEducationAndReferenceFoodAndDrinkGamesAndFunHealthAndFitnessLocalMoviesAndTVMusicAndAudioNewsAndMagazinesPhotographyProductivityShoppingSportsTravelAndTransportationWeather
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์ ๊ฐ์ง ์ ์์ |
๊ด๋ จ ํ์ผ
- 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์ผ๋ก ์ฒ๋ฆฌ๋ฅผ ํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
vocab(AddKeyword) {
"์ถ๊ฐํด์ค" {
"์ถ๊ฐํด์ฃผ์ธ์",
"์ถ๊ฐํด์ค๋",
"์ถ๊ฐํด์ฃผ๋ผ",
"์ถ๊ฐํด",
"์ถ๊ฐํด๋ผ",
...
}์ ํฌ ์๋ฆฌ๋ณด๊ณ ๋ ์ฌ๋ฃ๋ฅผ ์ถ๊ฐํ ๋ ์ฌ์ฉํ๋ ๋ฐํ์ธ "์ถ๊ฐํด์ค" ์ ๋์์ด๋ค์ ๊ตญ๋ฆฝ๊ตญ์ด์์์ ๊ฒ์ํ ํ ๋จ์ด๋ค์ enumํ์์ผ๋ก ์ถ๊ฐ๋ฅผ ํ์์ต๋๋ค.
๊ด๋ จํ์ผ
- ko-KR/voca : Ingredient.vocab.bxb, RecipeName.vocab.bxb
์๋ฅผ๋ค์ด ์์์ด๊ฑฐ๋ ์ปดํจํฐ ์ฃผ๋ณ๊ธฐ๊ธฐ ๋ฑ ์๋ฏธ๋ ๋ช
ํํ์ง ์์ง๋ง ๋๋ฌด ๋ง์์ ๋ชจ๋ ๊ฒ๋ค์ ๋ค ๋์ดํ ์ ์๋ ๊ฒฝ์ฐ๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น์? ์ด๋ด ๋ ์ฌ์ฉํด์ผํ๋ ๋ชจ๋ธ์ด ๋ฐ๋ก name์
๋๋ค. ์ผ๋ถ๋ ๋์ด์ด ๊ฐ๋ฅํ์ง๋ง, ํด๋นํ๋ ๋จ์ด๊ฐ ๋๋ฌด ๋ง์์ ์ ๋ถ ๋์ด์ด ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ name์ด ํจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ์
๋๋ค.
name์ ๊ฒฝ์ฐ enum๊ณผ๋ ๋ค๋ฅด๊ฒ Vocab์ด ๋ฐ๋์ ํ์ํ์ง ์์ผ๋, Vocab์ ์ถ๊ฐํ๋ ๊ฒฝ์ฐ ๋น
์ค๋น์๊ฒ ์ถ๊ฐ์ ์ธ hint๋ฅผ ์ค์ผ๋ก์จ ํ๊น
์ฑ๋ฅ์ ๋ํ ์๋ ์์ต๋๋ค.
์๋ฆฌ๋ณด๊ณ ์ฒ๋ผ ์์์ ์๋ก๋ค์๋ฉด ์นํจ, ์ง์ฅ๋ฉด, ํ๋ฒ๊ฑฐ ๋ฑ ์๋ง์ ์์ ๋ฐ์ดํฐ๊ฐ ๋ค์ด๊ฐ ์ ์์ํ
๋ฐ์. ๊ณผ์ฐ ์ง๊ตฌ์์ ์กด์ฌํ๋ ๋ชจ๋ ์์์ ์ด๋ฆ์ ๋ํด์ ๋ฐํ๋ฅผ ํ๋ํ๋ ์
๋ ฅํ ์ ์์๊น์? ๋ถ๊ฐ๋ฅ ํฉ๋๋ค. ๊ทธ๋์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ผ๋ก out of vocab training ์ด๋ผ๋ ๊ธฐ๋ฒ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
vocab(Ingredient){
"๊น์น",
"๋ผ์ง๊ณ ๊ธฐ",
...
}์์ ๊ฐ์ด vocab('๋ชจ๋ธ๋ช
')์ ์ ์ธํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์
๋ ฅํ๊ณ ๋ฐํ ํธ๋ ์ด๋์ ํ ๋ ๊ตฌ๋ถ์ด ๋๋ ๋ฌธ์ ์์ ๋จ์ด๋ฅผ name ๋ชจ๋ธ๋ก ์ ์ธํจ์ผ๋ก์จ ๋ชจ๋ ๋ฐ์ดํฐ์ ๋ํด ๋ฐํ๋ฅผ ๋ง๋ค ํ์๊ฐ ์๊ฒ ๋ฉ๋๋ค. ์์ธํ ๊ฒ์ "์ฌ๋ฃ๋ช
์ผ๋ก ๊ฒ์ํ๊ธฐ" ์์ ์ธ๊ธํ๋๋ก ํ๊ฒ ์ต๋๋ค.
text๋ ์์ ๋ ๊ฐ๋ก๋ ๋์ ํ ๋ฐ์ดํฐ์ ํํ๋ฅผ ์ ํ ์ ์์ ๋ ์ฌ์ฉํ๋ ๋ชจ๋ธ์
๋๋ค. ์๋ก๋ค์ด ์๋์ค์ ์ด๋ผ๋ ํค์๋์ ๋ํด์ ์ด๋ค ์ฌ๋์ "๋ด์ผ 8์ 30๋ถ ํ์ฌ๊ฐ์ผํด?" ๋ผ๊ณ ํ๊ณ ๋ค๋ฅธ ์ฌ๋์ "๋ด์ผ ์ผ์ " ์ด๋ผ๊ณ ํ๋ ๊ฒ ์ฒ๋ผ ๋ฐํ ๊ทธ๋ฃน์ ๋ค์ด์ฌ์ง ๋ง์ง๋ ๋ชจ๋ฅด๊ฒ ๊ณ ์ฌ์ด์ฆ๋ ๋ช
ํํ์ง ์๋ค๊ณ ํ ๋ text ํ์
์ ์ฌ์ฉํ์๋ฉด ๋ฉ๋๋ค. text๋ ์ด๋ ํ ๊ฐ์ด๋ ๊ฐ๋ฅํ๋ฏ๋ก ๋ฏธ๋ฆฌ ์์ธกํ ์ ์๋ ๊ฒฝ์ฐ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅํ๊ณ ์์ต๋๋ค. ๋ํ, enum, name๊ณผ ๋ค๋ฅด๊ฒ vocab์ ๊ฐ์ง ์ ์์ต๋๋ค. (์ ํฌ ์๋ฆฌ๋ณด๊ณ ์์๋ text์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ง ์์์ต๋๋ค.)
๋น ์ค๋น ์บก์ ๊ฐ๋ฐ์์ ๊ฐ์ฅ ์ค์ํ ๋ถ๋ถ์ ์ฐจ์งํ๋ ์์ญ์ ๋ฐํ๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ ์ด์ ๋ ๋น ์ค๋น ์บก์ ์์ฒด๊ฐ ๋ํํ ํ๋ซํผ์ด๋ฉฐ ๋ชจ๋ ๊ธฐ๋ฅ์ ์์์ด ๋ฐํ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ด๋ฒ ํํธ์์๋ ๋ฐํ์ ๋ํด์ ์๋ฆฌ๋ณด๊ณ ๋ฅผ ๊ฐ๋ฐํ๋ฉฐ ๋ง์ฃผ์ณค๋ ๋ฌธ์ ๋ค์ด๋ ์ด๋ค์์ผ๋ก ๊ฐ๋ฐ์ ํ์๋์ง์ ๋ํด ๊ธฐ์ ํ๊ฒ ์ต๋๋ค.
์๋ฆฌ๋ณด๊ณ ๋ ํน์ ์ฌ๋ฃ๋ค์ ๊ฐ์ง๊ณ ์ด๋ค ์๋ฆฌ๋ฅผ ํ ์ ์๋์ง ๋ณด์ฌ์ฃผ๋ ๊ธฐ๋ฅ์ ๊ฐ์ง๊ณ ์๋๋ฐ ์ฝ๊ฒ ๋งํด์ ๋ฐํ๋ฅผ ํตํด ์ ๋ ฅ๋ ์ฌ๋ฃ๋ค๋ก ๊ฒ์ํ๋ค๊ณ ์๊ฐํ์๋ฉด ๋ฉ๋๋ค.
๋ฐํ ์์
- "๋ผ์ง๊ณ ๊ธฐ๋ ๊น์น๋ ๋ํ ๋ ์ํผ ๋ณด์ฌ์ค"
- "๊ฐ์ฐ์ค๋ถ์๋ ์ฒญํฌ๋๋ ๊ทค์ด๋ ๊ฐ๋ญ์ฝฉ ํ๋๋ฒ ์กฐํํด์ค"
- "๋๋ฃฝ์ง๋ ์ ๊ณ ๊ธฐ๋ ์ํ ๋ง๋๋ ๋ฒ ๊ฒ์ํด"
์์ ์ธ๊ฐ์ง ๋ฐํ๋ ์ ๋ถ ๋ค๋ฅธ ๋ฐํ์ฒ๋ผ ๋ณด์ด์ง๋ง ์ผ์ ํ ํจํด์ด ์์ต๋๋ค. ์ฌ๋ฃ๋ช ์ผ๋ก ๊ฒ์ํ๊ธฐ ์ํ ๋ฐํ๋ ์๋์ ๊ฐ์ต๋๋ค.
ํจํด - [์ฌ๋ฃ]๋ [์ฌ๋ฃ] [๋ ์ํผ] [๋ณด์ฌ์ค]
**(๋ผ์ง๊ณ ๊ธฐ)[v:Ingredient]**๋ **(๊น์น)[v:Ingredeint]**๋ (๋ํ)[v:Ingredient] (๋ ์ํผ)[v:RecipeKeyword:๋ ์ํผ] (๋ณด์ฌ์ค)[v:SearchKeyword:๊ฒ์]
์๋ฆฌ๋ณด๊ณ ์์ SearchKeyword์ RecipeKeyword๋ฅผ ๋ฐ๋ก enum ์ผ๋ก ๋ง๋ค์ด ๋ฐํ๋ฅผ ๊ตฌ์ฑํ ์ด์ ๋ ์ค๋ณต๋ฐํ๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํจ์
๋๋ค. "๋ณด์ฌ์ค" , "์กฐํํด์ค" , "๊ฒ์ํด" ๋ฐํ๋ค์ ์๋ฏธ๋ ํฌ๊ฒ ๋ค๋ฅด์ง ์์ต๋๋ค. ๋ชจ๋ ๋๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ด๋๋๋ฐ ๊ตณ์ด ๊ฐ ๋จ์ด์ ๋ํ ๋ฐํ๋ฅผ ์ธ ๊ฐ๋ ๋ง๋ค ํ์๊ฐ ์์๊น์? ๋ง์ฐฌ๊ฐ์ง๋ก "ํ๋๋ฒ", "๋ง๋๋ ๋ฒ" ๋ชจ๋ "๋ ์ํผ" ์ ์๋ฏธ๊ฐ ๋์ผํฉ๋๋ค. ๊ทธ๋์ ์ ํฌ๋ ์ด๋ฐ ๋ถ๋ถ์ enum ์ผ๋ก ์ฒ๋ฆฌํ์ฌ vocab(...) ์ ์ ๋ฆฌ๋ฅผ ํ์์ต๋๋ค. ์ด ํจํด์ ํ๋์ ๋ฐํ๋ก ๋์ผํ ๋ฌธ์ฅ ๊ตฌ์กฐ ๋ด ์ ์์ด ์ฒ๋ฆฌ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
์์ ๋ฐ๋๋ก ์ฌ์ฉ์๊ฐ ์ฌ๋ฃ๊ฐ ์๋ ์์๋ช ์ผ๋ก๋ ๊ฒ์์ ์ํ ์๋ ์๊ฒ ๋ค๋ผ๊ณ ์๊ฐ์ ํ์ต๋๋ค. ๊ทธ๋์ ๋ฉ๋ด๋ช ์ผ๋ก ๋ฐํํ์ฌ ๊ฒ์ํ ์ ์๋ ๊ธฐ๋ฅ๋ ์ถ๊ฐํ์์ต๋๋ค.
๋ฐํ ์์
- "์ผ๊ณํ ๋ ์ํผ ๊ฒ์ํด์ค"
ํจํด - [๋ ์ํผ๋ช ] [์๋ฆฌ๋ฒ] [๋ณด์ฌ์ค]
[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:๊ฒ์]
์นผ๋ก๋ฆฌ ๊ฒ์์ ์ ๋ ฅํจํด์ด ๋ค์ํ๊ธฐ ๋๋ฌธ์, ์ด์/์ดํ๊ฐ ์๋ ๋ฌธ์ฅ๋ ๋ฐํ๋ก ๋ฃ์ด์ ๋ค์ํ ์๋๋ฆฌ์ค๋ฅผ ์ปค๋ฒํ๋๋ก ํ์ต๋๋ค.
์์์ ๊ฐ์ ๋ฌธ์ฅ๊ตฌ์กฐ ๋ด์ ์ ์์ด๋ 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๋ ํธ๋์ญ์
๋์ค ์กฐ๊ฑด์ ๋ค๋ฅด๊ฒ ํ์ฌ ๊ฒ์ํ๊ณ ์ถ์ ๋ ์ฌ์ฉ๋๋๋ฐ ํ์ฌ๋ ์ฌ๋ฃ๋ช
์ ์ด์ฉํ ๋ ์ํผ ๊ฒ์์์ ์ฌ๋ฃ๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐ ํ๋๋ฐ ์ฃผ๋ก ํ์ฉ๋๊ณ ์์ต๋๋ค. ์๋๋ ์์ ๋ฐํ์
๋๋ค.
- "์ํ๋ ๋ผ์ง๊ณ ๊ธฐ๋ฅผ ์ด์ฉํ ์๋ฆฌ๋ฒ ๊ฒ์ํด์ค"
- "์ํ ๋นผ๊ณ ๊ฒ์ํด์ค"
- "๊น์น ์ถ๊ฐํด์ ๊ฒ์ํด์ค"
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
var fail = require('fail');
if(db == undefined || db.length == 0){
// ์์ธ๋ฅผ ๋ฐ์์ํค๋ ๋ถ๋ถ
throw fail.checkedError('There is no process', 'NotFoundRecipes', null);
}//๋ฐ์ํ ์๋ฌ๋ action์ output์์ ์ฒ๋ฆฌํ๋ค.
output (RecipeCommitState){
throws{
//BeginRecipeSearch.js์์ throw๋ฅผ ํตํด ๋์ง ๋ ์ ์ํ ์ด๋ฆ
error (NotFoundRecipes){
on-catch{
// ์บก์ ๋์์ ์ ์งํจ
halt{
// ์๋จ์ ๋
ธ์ถ๋๋ ๋ฉ์์ง
dialog("๋ ์ํผ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.")
}
}
}
//๊ทธ ์ธ ์๋ฌ
unknown-error{
on-catch{
halt{
dialog("์๊ธฐ์น ๋ชปํ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.")
}
}
}
}
}์ฐธ๊ณ ์๋ฃ
-
Error Handling ๊ด๋ จ ์๋ฃ
https://bixbydevelopers.com/dev/docs/sample-capsules/samples/error-handling
๋น ์ค๋น์์ Http Request๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ์บก์์์ ์ ๊ณตํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ผํฉ๋๋ค.
๊ด๋ จ ํ์ผ
- code/lib : 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
//ResultView์์ ์ฌ์ฉ
app-launch{
//์ฐ๊ฒฐํ๊ณ ์ ํ๋ ๋ธ๋ผ์ฐ์ URL
payload-uri("#{value(this.url)}")
}์ฐธ๊ณ ์๋ฃ
์ธ์ฝ๋ฉ๋ ๊ฒ์์ด๋ฅผ parameter๋ก ๋ฃ์ด Youtube ์๋ฒ๋ก ์ ์ก์ ํ๋ฉด JSON ํํ๋ก ๊ฒ์๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ ์ ์๋ API ์ ๋๋ค. ๋ฐํ๋๋ ๊ฒฐ๊ณผ์๋ thumbnail ๋ฟ๋ง ์๋๋ผ ๋์์์ ๋ํ ์ค๋ช ๋ฑ ํ์ํ ๋ฐ์ดํฐ๋ง ์ถ์ถํ์ฌ์ ์ฌ์ฉํ์ค ์ ์์ต๋๋ค. Youtube Search API๋ฅผ ์ฌ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
- API Key๋ฅผ ์ด์ฉํ์ฌ ๋จ์ ๊ฒ์
- OAuth ์ธ์ฆ์ ํตํ์ฌ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
์ด๋ ๊ฒ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋๋ฐ, OAuth ๊ฐ์ ๊ฒฝ์ฐ์๋ Google ๋ก๊ทธ์ธ๊ณผ ๊ฐ์ ์จ๋ ํํฐ ์ฌ์ฉ์ด ๊ฐ๋ฅํ ์ ์ด ์์ง๋ง ์ ํฌ ์บก์์์๋ ๋ก๊ทธ์ธ์ด๋ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์ฌ์ฉํ ํ์๊ฐ ์์๊ธฐ ๋๋ฌธ์ API Key๋ฅผ ์ด์ฉํ์ฌ ๊ฐ๋จํ๊ฒ ์ฟผ๋ฆฌ๋ฅผ ์ ์กํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๋ ํ์์ผ๋ก ๊ฐ๋ฐ์ ํ์์ต๋๋ค.
์๋์ ๋ณด์๋ฉด URL ์ฃผ์๊ฐ ์๋๋ฐ ๋ค์ด๊ฐ๋ณด์๋ฉด, ์์ ๋ค์ ํ์ธํ ์ ์๋๋ฐ JAVA์ธ์ด๋ก ์์ฑ๋ sample code๊ฐ ์์ต๋๋ค. ํด๋น ์ฝ๋์ ํต์ฌ์ ์ธ ๋ถ๋ถ๋ง ์ค๋ช ์ ๋๋ฆฌ๊ฒ ์ต๋๋ค.
/** 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 ํ์ผ์ ๋ฃ์ด์ค์ผ๋ก์จ ์ฌ์ฉํ์ค ์ ์์ต๋๋ค. ์ธ์ฆ๋ ๊ฐ์ ์ ํํ๊ฒ ์
๋ ฅํ๊ฒ ๋๋ฉด ์ ์์ ์ผ๋ก ์๋ํ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
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๊ฐ ๋ง๋ค์ด์ ธ ์๊ธฐ ๋๋ฌธ์ ์์ฃผ ํธํ๊ฒ ๊ฐ์ ์ป์ ์ ์์ต๋๋ค.
์ฐธ๊ณ ์๋ฃ
-
Youtube API
https://developers.google.com/youtube/v3/docs/search/list?hl=ko
-
Google Cloud Platform
-
OAuth 2.0



