230330(λͺ©)
π μ±μ₯μΌμ§ 4.0
μ±
ν볡ν μ΄κΈ°μ£Όμμ(μ¨μΈ λ€μ΄μ΄)
μ λ΄μ©μ μκ·Ήλ°μ μμνλ μλ°ν μ±μ₯κΈ°λ‘
μ΄μμλ κ½κ³Ό μ£½μ κ½μ μ΄λ»κ² ꡬλ³νλκ°?
μ±μ₯νκ³ μλ κ²μ΄ μ΄μ μλ κ²μ΄λ€.
μλͺ μ μ μΌν μ¦κ±°λ μ±μ₯μ΄λ€!
π³ (1.0)ν€μλ
μ΅λν κ°λ¨νκ² μ 리, μΆνμ 보면μ μ€μ€λ‘ μ€λͺ
π (2.0)κ²½ν μμ£Όλ‘
λ¨μ μ 보λ₯Ό μ λ¬νκΈ°λ³΄λ€ λ¬΄μμ λ°°μ κ³ μ΄λ»κ² ν΄κ²°νλμ§ μ§§κ³ κ°λ¨νκ² μμ±
βοΈ (3.0)μ ν΄μ§ ν νλ¦Ώμ λ§μΆ°μ
ν€μλ, κ²½ν λͺ¨λ μ’λ€. λ€λ§ λ§€μΌ μμ±νκΈ°λ‘ λ§μ λ¨Ήμλ§νΌ ν΅μ¬λ§ κ°κ²°νκ² μ 리ν μ μκ² ν νλ¦Ώμ μμ±
(3.1)230102λΆν° μμλλ νμ΅μ κ΄ν λ΄μ© μΆκ°
(3.2)230313λΆν° μ’λ κ²½ν, κ°μ μμ£Όμ λ΄μ©λ λ΄κΈ°!
πΎ (4.0)νμ΅ ν€μλμμ μ΅λν κ°λ¨ν μ 보 μ 곡, κ³ λ―Όμμ λ΄ κ²½νμ μμΈν μ μ!
π μ€λμ νμ΅ ν€μλ
Node.js, express μλ² λ¦¬ν©ν λ§
import * as express from 'express';
import * as bodyParser from 'body-parser'; // μμ²μ λν bodyλ₯Ό νμ±νλ μν
import * as dotenv from 'dotenv'; // .env νμΌμ ν΅ν΄ 보μμ κ°λ €μΌν λ°μ΄ν°λ₯Ό λ°λ‘ λλ€.
import * as cors from 'cors'; // CORS μλ¬λ₯Ό ν΄κ²°νκΈ° μν¨
import * as mongoDb from 'mongodb'; // mongodbμ μ°κ²°!
dotenv.config(); // μ΄μ μλμμ process.envλ‘ μ΄λ€ κ°λ€μ κ°μ Έμ¬ μ μλ€.(μ¨κΈΈ μ μλ€.)
async function main() {
const MongoClient = mongoDb.MongoClient;
const client = new MongoClient(
`mongodb+srv://${process.env.MONGO_USER_NAME}:${process.env.MONGO_PASSWORD}@${process.env.MONGO_CLUSTER_NAME}.jy2zpck.mongodb.net/?retryWrites=true&w=majority`,
);
await client.connect();
const db = client.db('data-base-name');
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.listen(process.env.PORT, () => {
console.log('listening on 1116');
});
app.get('/top10', (req, res) => {
res.json('ν
μ€νΈ λ¬Έμμ΄');
});
app.get('/search', async (req, res) => {
const query = req.query.q; // μμ²μ query stringμ λ΄κ²¨μλ κ°μ λ°μμ¨λ€.
const collection = db.collection('product');
const result = await collection
.find({ keywords: { $regex: `${query}`, $options: 'i' } })
.toArray();
if (result.length === 0) {
res.json([{ keywords: 'ν΄λΉνλ μνμ΄ μμ΅λλ€.' }]);
} else {
res.json(result);
}
});
}
main();
μμ κ°μ νλ¦μ΄ λ mongoDBμμ μ°κ²° λ° expressλ₯Ό ν΅ν μλ²λ₯Ό λμ°κΈ°μ νλ¦μ΄ 보μ΄λ κ² κ°μ μμ νμλ€.
MongoClient
μ mongoDB urlμ ν΅ν΄ client κ°μ²΄λ₯Ό λ§λ€μ΄ μ€λ€.- client κ°μ²΄μ
connect()
λ©μλλ‘ μ°κ²°ν΄μ€λ€. - clientμ db λ©μλλ₯Ό ν΅ν΄ λ§λ€μ΄λμ database μ΄λ¦μ λ¬Έμμ΄λ‘ μ λ¬νλ€.
- μ΄μ μ΄ db κ°μ²΄μμ νμν λλ§λ€ collectionμΌλ‘ μ κ·Όνμ¬ μλ² api λ‘μ§κ³Ό ν¨κ» μ¬μ©νλ©΄ λλ€.
- μ΄ λ, mongoDBμμ collectionμ SQLμ ν μ΄λΈ νλμ κ°λ€κ³ μκ°νλ©΄ λλ€.
λλ°μ΄μ€(Debounce)
- μ΄λ²€νΈλ₯Ό κ·Έλ£ΉμΌλ‘ λ¬Άκ³ νΉμ μκ°μ΄ μ§λ ν, λ§μ§λ§ νλμ μ΄λ²€νΈλ§ λ°μνλλ‘ νλ λ°©λ²
- setTimeoutκ³Ό clearTimeoutμΌλ‘ ꡬνν΄λ³Ό μ μλ€.
export const debounce = (callback: (e: Event) => void, delay: number) => {
let timerId: ReturnType<typeof setTimeout>;
return (event: Event) => {
if (timerId) clearTimeout(timerId);
timerId = setTimeout(callback, delay, event);
};
};
// νμ© μμ
this.setEventListener(
'click',
debounce(() => {
this.searchListComponent.deleteAllChild();
if (this.searchListComponent.element.style.display !== 'flex') {
this.searchListComponent.show();
dimLayer.on();
}
fetch('http://localhost:1116/search?q=')
.then((res) => res.json())
.then((data) =>
data.slice(0, 10).forEach((d: ProductData) => {
this.searchListComponent.addChildHtml(`<li>${d.keywords}</li>`);
}),
);
}, 300),
);
- debounceλ₯Ό μ΄μ©νμ¬ κ³μ λλ click μ΄λ²€νΈμ λ°λ₯Έ fetch λ°μμ λ§μ§λ§ 1λ²λ§ λ°μνκ² ν΄μ£Όμλ€.
π μ€λμ κ³ λ―Ό ν€μλ
api λ‘μ§
μλ² κ°λ°μλ μλμ§λ§, μ’λ 볡μ‘ν api λ‘μ§μ λ§λ€κ³ μ²λ¦¬νλμ§ κΆκΈνλ€. λ΄κ° λ§λ apiμ²λΌ μ λ κ² κ°λ¨νμ§λ μμ κ±° κ°μλ°..!
π μμ½ λ° ν루 κ°λ¨ νκ³
μ΄μ κΉμ§λ§ ν΄λ κ΄ν μλ² λμ°λ κ²λ ν΄λ³΄κ² λ€κ³ 무리νλ μΆμμ§λ§, μ΄λ κ² μ§μ μλ²λ₯Ό λμ°κ³ apiλ₯Ό λ§λ€μ΄μ μμ²μ λν μλ΅μ μ²λ¦¬ν΄λ³΄λ λ무 μ¬λ―Έμκ³ μ 체μ μΈ νλ¦μ μ΄ν΄νλλ° λμμ΄ λ κ² κ°λ€. μμ§ UIμͺ½ ꡬνμ΄ λ―Έν‘νκ³ λ°μμ¨ μλ΅ λ°μ΄ν°λ₯Ό μ΄λ»κ² μ’λ μ κ°κ³΅ν μ§κ° κ³ λ―Όμ΄κΈ΄νμ§λ§..!
μ€λμ μν μ
- κ°λ¨ν apiλ₯Ό λ§λ€κ³ μνλ responseλ₯Ό μ λ¬ν κ²
- λλ°μ΄μ€λ₯Ό ν΅ν΄ κ³μλλ μ΄λ²€νΈλ₯Ό λ§κ³ μλ²μ λΆνκ° κ±Έλ¦¬μ§ μκ² μ²λ¦¬νμ
μ€λμ μμ¬μ΄ μ
- κ°λ° μλκ° λΉ λ₯΄μ§ λͺ»ν κ² κ°λ€.
- μμΌλ‘ μ½λλ₯Ό 지 λλ λ¨Έλ¦Ώμμ λͺ νν μ€κ³λ₯Ό κ°κ³ μν΄μΌκ² λ€λ μκ°μ΄ λ λ€.
μ°Έκ³
- κ°μ
- express 곡μλ¬Έμ