Implement API endpoints in Node.js server for greeting and notes management, and update README with new endpoint details.
This commit is contained in:
@@ -9,7 +9,7 @@ Edit di Cursor di Mac, commit, lalu `git push`. Deploy ke `ubuntu-vm` terpisah (
|
|||||||
| Folder | Pelajaran | Port di VM |
|
| Folder | Pelajaran | Port di VM |
|
||||||
|--------|-----------|------------|
|
|--------|-----------|------------|
|
||||||
| `pelajaran-1/` | Nginx + HTML statis | `8088` |
|
| `pelajaran-1/` | Nginx + HTML statis | `8088` |
|
||||||
| `pelajaran-2/` | Node.js di Docker | `8091` |
|
| `pelajaran-2/` | Node.js di Docker — lihat `pelajaran-2/PELAJARAN-2.md` | `8091` |
|
||||||
|
|
||||||
## Git remote
|
## Git remote
|
||||||
|
|
||||||
|
|||||||
+185
-4
@@ -1,13 +1,112 @@
|
|||||||
const http = require('http');
|
const http = require('http');
|
||||||
|
|
||||||
|
|
||||||
|
const notes = [];
|
||||||
|
|
||||||
// fungsi ini dipanggil ketika ada request
|
// fungsi ini dipanggil ketika ada request
|
||||||
function handleRequest(request, response) {
|
function handleRequest(request, response) {
|
||||||
console.log('Ada yang minta:', request.url);
|
console.log('Ada yang minta:', request.url);
|
||||||
|
|
||||||
const waktu = new Date().toISOString("id-ID");
|
const waktu = new Date().toISOString("id-ID");
|
||||||
|
|
||||||
|
// --- CABANG API ---
|
||||||
|
if (request.url === '/api/hello') {
|
||||||
response.writeHead(200, {
|
response.writeHead(200, {
|
||||||
"Content-Type": "text/html; charset=utf-8",
|
'Content-Type': 'application/json; charset=utf-8'
|
||||||
|
})
|
||||||
|
response.end(
|
||||||
|
JSON.stringify({
|
||||||
|
message: 'Halo dari API Node',
|
||||||
|
waktu: waktu,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return; // penting: berhenti disini, jangan kirim HTML juga.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.url === '/api/greet' && request.method === 'POST') {
|
||||||
|
let body = '';
|
||||||
|
|
||||||
|
request.on('data', function(chunk) {
|
||||||
|
body += chunk;
|
||||||
|
})
|
||||||
|
|
||||||
|
request.on('end', function() {
|
||||||
|
let name = 'teman';
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(body);
|
||||||
|
if (parsed.name) {
|
||||||
|
name = String(parsed.name)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Gagal membaca body:', err);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.writeHead(200, {
|
||||||
|
'Content-Type': 'application/json; charset=utf-8'
|
||||||
|
})
|
||||||
|
response.end(
|
||||||
|
JSON.stringify({
|
||||||
|
sapaan: `Halo, ${name}!`,
|
||||||
|
waktu: new Date().toISOString(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.url === '/api/notes' && request.method === 'GET') {
|
||||||
|
response.writeHead(200, {
|
||||||
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
|
})
|
||||||
|
response.end(JSON.stringify(notes));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.url === '/api/notes' && request.method === 'POST') {
|
||||||
|
let body = '';
|
||||||
|
|
||||||
|
request.on('data', function(chunk) {
|
||||||
|
body += chunk;
|
||||||
|
})
|
||||||
|
request.on('end', function() {
|
||||||
|
let teks = '';
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(body);
|
||||||
|
if (parsed.teks) {
|
||||||
|
teks = String(parsed.teks).trim();
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Gagal membaca body:', err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!teks) {
|
||||||
|
response.writeHead(400, {
|
||||||
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
|
})
|
||||||
|
response.end(JSON.stringify({
|
||||||
|
error: 'Teks tidak boleh kosong',
|
||||||
|
}))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const note = {
|
||||||
|
id: Date.now(),
|
||||||
|
teks: teks,
|
||||||
|
waktu: new Date().toISOString(),
|
||||||
|
}
|
||||||
|
notes.push(note);
|
||||||
|
|
||||||
|
response.writeHead(201, {
|
||||||
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
|
})
|
||||||
|
response.end(JSON.stringify(note));
|
||||||
|
return;
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// --- CABANG HTML ---
|
||||||
|
response.writeHead(200, {
|
||||||
|
'Content-Type': 'text/html; charset=utf-8'
|
||||||
});
|
});
|
||||||
|
|
||||||
response.end(`<!DOCTYPE html>
|
response.end(`<!DOCTYPE html>
|
||||||
@@ -18,13 +117,95 @@ function handleRequest(request, response) {
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Halo dari Node</h1>
|
<h1>Halo dari Node</h1>
|
||||||
<p>Ini dibuat ulang setiap request, bukan file HTML diam.</p>
|
<p>Halaman ini dari server. Tombol di bawah memanggil API dari browser.</p>
|
||||||
<p>Waktu server: <strong>${waktu}</strong></p>
|
<p>Waktu saat halaman dibuat: <strong>${waktu}</strong></p>
|
||||||
<p>Path yang diminta: <code>${request.url}</code></p>
|
<button type="button" id="tombol">Panggil /api/hello</button>
|
||||||
|
<p id="hasil">Belum dipanggil.</p>
|
||||||
|
<hr />
|
||||||
|
<h2>Coba POST</h2>
|
||||||
|
<label>
|
||||||
|
Nama: <br />
|
||||||
|
<input type="text" id="nama" placeholder="namamu" /><br />
|
||||||
|
</label>
|
||||||
|
<button type="button" id="kirim">Kirim ke /api/greet</button>
|
||||||
|
<p id="sapaan">Belum ada sapaan.</p>
|
||||||
|
<hr />
|
||||||
|
<h2>Caatan (memori server)</h2>
|
||||||
|
<ul id='daftar-notes'></ul>
|
||||||
|
<input type='text' id='teks-note' placeholder='Tulis catatan baru...' />
|
||||||
|
<button type='button' id='tambah-note'>Tambah</button>
|
||||||
|
<script>
|
||||||
|
const tombol = document.getElementById("tombol");
|
||||||
|
const hasil = document.getElementById("hasil");
|
||||||
|
tombol.addEventListener("click", async function () {
|
||||||
|
hasil.textContent = "Memuat...";
|
||||||
|
try {
|
||||||
|
const response = await fetch("/api/hello");
|
||||||
|
const data = await response.json();
|
||||||
|
hasil.textContent = data.message + " | " + data.waktu;
|
||||||
|
} catch (err) {
|
||||||
|
hasil.textContent = "Gagal: " + err.message;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const inputNama = document.getElementById("nama");
|
||||||
|
const tombolKirim = document.getElementById("kirim");
|
||||||
|
const teksSapaan = document.getElementById("sapaan");
|
||||||
|
tombolKirim.addEventListener("click", async function () {
|
||||||
|
teksSapaan.textContent = "Mengirim...";
|
||||||
|
try {
|
||||||
|
const response = await fetch("/api/greet", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
nama: inputNama.value,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
const data = await response.json();
|
||||||
|
teksSapaan.textContent = data.sapaan + " (" + data.waktu + ")";
|
||||||
|
} catch (err) {
|
||||||
|
teksSapaan.textContent = "Gagal: " + err.message;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const daftarNotes = document.getElementById("daftar-notes");
|
||||||
|
const inputNote = document.getElementById("teks-note");
|
||||||
|
const tombolNote = document.getElementById("tambah-note");
|
||||||
|
|
||||||
|
async function muatNotes() {
|
||||||
|
const response = await fetch("/api/notes");
|
||||||
|
const data = await response.json();
|
||||||
|
daftarNotes.innerHTML = "";
|
||||||
|
data.forEach(function (note) {
|
||||||
|
const li = document.createElement("li");
|
||||||
|
li.textContent = note.teks + " (" + note.waktu + ")";
|
||||||
|
daftarNotes.appendChild(li);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
tombolNote.addEventListener("click", async function () {
|
||||||
|
await fetch("/api/notes", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ teks: inputNote.value }),
|
||||||
|
});
|
||||||
|
inputNote.value = "";
|
||||||
|
await muatNotes();
|
||||||
|
});
|
||||||
|
|
||||||
|
// saat halaman dibuka, ambil daftar yang sudah ada
|
||||||
|
muatNotes();
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>`);
|
</html>`);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --- Mulai server ---
|
||||||
const server = http.createServer(handleRequest);
|
const server = http.createServer(handleRequest);
|
||||||
|
|
||||||
server.listen(3000, function() {
|
server.listen(3000, function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user