နားလည်ထားရမယ့် အချက်
Lesson အားလုံးအထိ Kibana Dev Tools ရဲ့ shorthand HTTP syntax ကို သင်ယူခဲ့ပေမယ့် production application code ထဲမှာတော့ raw `fetch`/`curl` calls ကို manually string-build ပြီးသုံးတာက error-prone ဖြစ်ပါတယ်—URL encoding, JSON serialization, connection pooling, retry logic တွေကို manually handle ရမှာဖြစ်လို့ပါ။ Official `@elastic/elasticsearch` Node.js client ကတော့ ဒီအလုပ်တွေအားလုံးကို abstract လုပ်ပေးပြီး TypeScript type definitions ပါလာလို့ query DSL object ကို compile-time မှာ type-check လုပ်နိုင်ပါတယ်—raw JSON string ထဲမှာ typo ရိုက်မိရင် runtime error ဖြစ်မှသာ တွေ့ရမယ့်အစား editor ထဲမှာချက်ချင်း error မြင်ရနိုင်ပါတယ်။ Client library ကို connect လုပ်တဲ့အခါ connection pooling ကို built-in အနေနဲ့ handle ပေးထားလို့ request တစ်ခုစီအတွက် new TCP connection ဖန်တီးစရာမလိုတော့ပါ—Node.js server process တစ်ခုအတွက် client instance တစ်ခုတည်းကို singleton pattern နဲ့ share သုံးသင့်ပါတယ်။ Client ရဲ့ method call တွေက Query DSL structure ကို တိုက်ရိုက် JavaScript/TypeScript object အဖြစ် map လုပ်ထားလို့ Kibana Dev Tools ထဲက query တွေကို port လုပ်ရတာ ရိုးရှင်းပါတယ် (`GET /tutorials/_search` + JSON body → `client.search({ index: 'tutorials', query: {...} })`)—ဒါက Lesson 7 မှာ ကတိပြောထားခဲ့တဲ့ "Dev Tools syntax ကို client method call အဖြစ် port ရိုးရှင်းတယ်" ဆိုတာကို လက်တွေ့ ဒီနေရာမှာ ပြသနေပါတယ်။
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
Tutorial Platform ရဲ့ Next.js API route (`/api/search`) ထဲမှာ request တစ်ခုစီအတွက် new `Client` instance ဖန်တီးမယ့်အစား module-level singleton client ကို export လုပ်ပြီး route handler တွေအားလုံးက import လုပ်ပြီး reuse လုပ်မယ်—connection pool ကို process တစ်ခုတည်းအတွက် share လုပ်ဖို့ပါ။ Dev Tools ထဲက `match` + `bool` query ကို TypeScript object literal အဖြစ် ရေးပြီး `client.search<TutorialDoc>({ index: 'tutorials', query: {...} })` ကို `await` သုံးမယ်—generic type parameter `TutorialDoc` ကို ထည့်ထားလို့ `hits.hits[].source` ကို access တဲ့အခါ field name typo ကို compile-time မှာ catch နိုင်ပါတယ်။ Environment variable ထဲက Elasticsearch URL/API key ကို client config ထဲ pass ပြီး local dev/production ကို config တစ်ခုတည်းက switch လုပ်နိုင်အောင် ဆောက်မယ်။
အတူတူ စမ်းရေးကြည့်မယ်
import { Client } from '@elastic/elasticsearch';
export const esClient = new Client({
node: process.env.ELASTICSEARCH_URL,
auth: { apiKey: process.env.ELASTICSEARCH_API_KEY! },
});
interface TutorialDoc {
title: string;
body: string;
difficulty: string;
}
export async function searchTutorials(term: string) {
const result = await esClient.search<TutorialDoc>({
index: 'tutorials',
query: { match: { body: term } },
});
return result.hits.hits.map((hit) => hit._source);
}Type-safe search function တစ်ခု ရေးနိုင်ပြီး tutorial documents array ကို TypeScript type ဖြင့် ပြန်ရမည်။၅ မိနစ် စမ်းကြည့်
`Client` singleton ကိုသုံးပြီး `difficulty` field ဖြင့် filter လုပ်ထားသော `bool` query (`match` + `filter`) ကို run သော `searchByDifficulty(term, difficulty)` function တစ်ခု ရေးပါ—return type ကို `TutorialDoc[]` ဖြစ်စေပါ။
သတိလေးတစ်ချက်
API route/function ခေါ်တိုင်း `new Client(...)` ကို ထပ်ခါထပ်ခါ instantiate ခြင်း—connection pool ကို share မရတော့ဘဲ TCP connection အများကြီး ဖွင့်ပြီး resource waste ဖြစ်ပါတယ်။
`client.search()` ရဲ့ result ကို `TutorialDoc` type parameter မထည့်ဘဲ `any` အဖြစ် ချန်ထားခြင်း—field name typo (`hits.hits[].source.titl`) ကို compile-time မှာ လုံးဝ catch မရတော့ပါ။
elasticsearch-js — GitHub — Elastic