Dasar-dasar Node JS & Express (III). Dasar-Dasar Node JS & Express (III) Catatan Bacaan: BACA Rute




  • Terjemahan

Bagi programmer baru, pengembangan untuk Node.js bisa terasa seperti mimpi buruk. Penyebabnya adalah fleksibilitas platform dan kurangnya pedoman yang jelas. Namun nyatanya, semuanya tidak begitu menakutkan.


Misalnya, berikut adalah tugas umum: mengembangkan REST API, bagian server dari suatu aplikasi. Banyaknya kemampuan Node sendiri dan banyaknya modul tambahan yang dapat membantu memecahkan masalah ini dapat membawa seorang pemula ke jalan buntu karena banyaknya pilihan. Persoalan utama di sini adalah pemilihan komponen dan cara kerjanya.

Salah satu cara untuk membuat aplikasi sisi server adalah dengan menggunakan kombinasi Node.js, kerangka Express dan DBMS MongoDB. Faktanya, hari ini saya akan berbicara tentang cara membuat mockup API yang berfungsi yang dapat menjadi dasar untuk hampir semua aplikasi. Di sini kita akan mengimplementasikan rute REST dasar, berinteraksi dengan API melalui HTTP, dan menggunakan opsi database sederhana.

Agar berhasil menguasai materi ini, Anda perlu memahami apa itu REST API, memahami operasi CRUD, dan memiliki pengetahuan dasar tentang JavaScript. Saya menggunakan ES6 di sini, tidak ada yang terlalu rumit, kebanyakan fungsi panah.

Kami akan mengembangkan kerangka backend untuk aplikasi pencatatan yang mirip dengan Google Keep. Dalam hal ini, keempat tindakan CRUD dapat dilakukan dengan catatan, yaitu membuat, membaca, memperbarui, dan menghapus.

Persiapan awal

Jika Anda belum memiliki Node, sekarang saatnya menginstalnya. Setelah instalasi, buat folder dan jalankan perintah untuk menginisialisasi proyek baru di dalamnya:

Npm init
Selama inisialisasi, jawablah pertanyaan, khususnya, beri nama aplikasi yang “terkenal” (atau, jika Anda mau, nama lain).

File tersebut sekarang akan muncul di folder paket.json. Ini berarti Anda dapat mulai menginstal paket tambahan yang bergantung pada proyek tersebut.

Kami berencana menggunakan Express sebagai kerangka kerja. Sistem manajemen basis datanya adalah MongoDB. Selain itu, sebagai alat bantu untuk bekerja dengan JSON, kami menggunakan paket body-parser. Mari kita instal semua ini:

Npm install --simpan pengurai tubuh mongodb ekspres
Selain itu, saya sangat merekomendasikan menginstal Nodemon sebagai ketergantungan dev. Ini adalah paket kecil sederhana yang, ketika file berubah, secara otomatis me-restart server.

Untuk menginstal paket ini, jalankan perintah:

Npm instal --save-dev nodemon
Kemudian Anda dapat menambahkan skrip berikut ke file tersebut paket.json:

// package.json "scripts": ("dev": "nodemon server.js" ),
Siap paket.json akan terlihat seperti ini:

// package.json ( "nama": "terkenal", "versi": "1.0.0", "deskripsi": "", "utama": "server.js", "scripts": ( "dev": "nodemon server.js", "penulis": "", "lisensi": "ISC", "dependensi": ( "body-parser": "^1.15.2", "express": "^4.14.0 " , "mongodb": "^2.2.16" ), "devDependencies": ( "nodemon": "^1.11.0" ) )
Sekarang mari kita membuat file server.js dan mari mulai mengerjakan API.

pelayan

Mari kita mulai dengan menghubungkan dependensi dalam file server.js.

// server.js const express = require("ekspres"); const MongoClient = memerlukan("mongodb").MongoClient; const bodyParser = memerlukan("body-parser"); aplikasi const = ekspres();
Kami akan menggunakan MongoClient untuk berinteraksi dengan database. Selain itu, di sini kita menginisialisasi konstanta aplikasi, yang melambangkan aplikasi kita, dengan sebuah instance dari kerangka Express. Agar server dapat berfungsi, yang tersisa hanyalah memberi tahu aplikasi agar mulai mendengarkan permintaan HTTP.

Di sini kami menentukan port dan mulai mendengarkan sebagai berikut:

// port konst server.js = 8000; aplikasi.dengarkan(port, () =>
Sekarang, jika Anda menjalankan perintah npm run dev (atau - node server.js jika Anda tidak menginstal Nodemon), pesan akan muncul di terminal: “We are live on port 8000”.

Jadi server sedang berjalan. Tapi sekarang dia tidak melakukan apa pun yang berguna. Mari kita cari tahu.

Rute yang menargetkan operasi CRUD

Kami berencana membuat 4 rute. Yaitu:
  • BUAT – membuat catatan.
  • BACA – baca catatan.
  • PEMBARUAN – memperbarui catatan.
  • HAPUS—menghapus catatan.
Setelah Anda menguasai skema ini, Anda akan dapat memahami bagaimana, menggunakan Node, mengatur hampir semua rute REST yang diperlukan.

Untuk menguji API, Anda memerlukan sesuatu yang dapat mensimulasikan permintaan dari sisi klien aplikasi. Sebuah program luar biasa bernama Postman akan membantu kita mengatasi masalah ini. Ini memungkinkan Anda untuk melakukan permintaan HTTP sederhana dengan isi dan parameter tertentu.

Instal Tukang Pos. Sekarang semuanya siap untuk mengkonfigurasi rute.

Tentang struktur proyek

Kebanyakan tutorial Node.js (dan banyak aplikasi kehidupan nyata) menempatkan semua rute dalam satu file besar rute.js. Saya tidak terlalu menyukai pendekatan ini. Jika Anda mengatur file ke dalam folder berbeda, ini akan meningkatkan keterbacaan kode dan membuat aplikasi lebih mudah dikelola.

Aplikasi kami tidak bisa disebut besar, tetapi saya mengusulkan untuk melakukan segalanya sebagaimana mestinya, dengan mempertimbangkan skalanya yang sederhana. Buat folder berikut: folder aplikasi, dan di dalamnya - rute. Di folder rute membuat file indeks.js Dan note_routes.js. Dengan kata lain, struktur proyek akan terlihat seperti ini: root > aplikasi > rute > index.js Dan note_routes.js.

Aplikasi mkdir cd aplikasi mkdir rute cd rute sentuh index.js sentuh note_routes.js
Struktur ini mungkin tampak mubazir untuk aplikasi kecil, namun akan sangat berguna dalam sistem yang lebih besar yang dibangun berdasarkan contoh kita. Selain itu, yang terbaik adalah memulai proyek apa pun dengan menggunakan praktik terbaik yang ada.

Membuat catatan: BUAT rute

Mari kita mulai dengan rute CREATE. Untuk melakukan ini, kami akan menjawab pertanyaan: “Bagaimana cara membuat catatan?”
Sebelum kita mulai membuat catatan, kita perlu memperluas infrastruktur aplikasi. Di Express, rute dibungkus dalam fungsi yang menggunakan instance Express dan database sebagai argumen.

Ini mungkin terlihat seperti ini:

// rute/note_routes.js module.exports = fungsi(aplikasi, db) ( );
Anda sekarang dapat mengekspor fungsi ini melalui indeks.js:

// rute/index.js const noteRoutes = memerlukan("./note_routes"); module.exports = function(app, db) ( noteRoutes(app, db); // Akan ada penangan rute lain di sini nanti );
Kami mengimpor apa yang kami dapatkan server.js:

// server.js const express = require("ekspres"); const MongoClient = memerlukan("mongodb").MongoClient; const bodyParser = memerlukan("body-parser"); aplikasi const = ekspres(); port konstan = 8000; memerlukan("./aplikasi/rute")(aplikasi, ()); app.listen(port, () => ( console.log("Kami siaran langsung di " + port); ));
Harap dicatat bahwa karena kita belum mengkonfigurasi database, objek kosong dilewatkan sebagai argumen kedua.

Sekarang kita membuat rute CREATE. Sintaksnya di sini cukup sederhana:

Module.exports = function(app, db) ( app.post("/notes", (req, res) => ( // Kita akan membuat catatan di sini. res.send("Hello") )); );
Saat aplikasi menerima permintaan POST melalui jalur '/notes', aplikasi akan mengeksekusi kode di dalam fungsi callback, meneruskannya ke objek permintaan (yang berisi parameter permintaan atau data JSON) dan objek respons (yang, tentu saja, digunakan untuk respons).

Apa yang telah kita capai sudah bisa diuji. Mari kita kirim, menggunakan Tukang Pos, permintaan POST ke alamat tersebut localhost:8000/catatan.


Tanggapan terhadap permintaan tersebut haruslah “Halo”

Besar. Rute pertama telah dibuat. Langkah selanjutnya adalah menambahkan parameter ke permintaan, memprosesnya di API, dan terakhir menyimpan catatan di database.

Parameter permintaan

Di Tukang Pos, buka tab Tubuh dan tambahkan beberapa pasangan nilai kunci dengan memilih tombol radio x-www-form-urlencoded. Yaitu, kunci pertama adalah judul, nilainya adalah Judul Catatan Saya. Kunci kedua - tubuh, nilainya adalah Catatan yang bagus sekali.

Ini akan menambahkan data yang disandikan ke permintaan yang dapat diproses oleh API.


Judul catatan saya, dan postingannya sendiri, sangat sederhana, tetapi di sini Anda dapat menunjukkan imajinasi Anda

Dalam berkas note_route.js, cukup cetak isi catatan ke konsol.

// note_routes.js module.exports = function(app, db) ( app.post("/notes", (req, res) => ( console.log(req.body) res.send("Halo") ) );
Coba kirim permintaan menggunakan Tukang Pos dan Anda akan melihat... tidak terdefinisi.

Sayangnya, Express tidak dapat menangani formulir yang dikodekan URL sendiri. Di sini paket body-parser yang diinstal sebelumnya akan membantu kami.

// server.js const express = require("ekspres"); const MongoClient = memerlukan("mongodb").MongoClient; const bodyParser = memerlukan("body-parser"); aplikasi const = ekspres(); port konstan = 8000; app.use(bodyParser.urlencoded(( diperpanjang: true ))); memerlukan("./aplikasi/rute")(aplikasi, ()); app.listen(port, () => ( console.log("Kami siaran langsung di " + port); ));
Sekarang, setelah menjalankan permintaan POST, tubuhnya dapat dilihat di terminal sebagai objek.

( judul: "Judul Catatan Saya", isi: "Catatan yang sangat bagus." )
Agar rute pertama berfungsi sepenuhnya, yang tersisa hanyalah mengkonfigurasi database dan menambahkan catatan ke dalamnya.

Untuk membuat dan mengkonfigurasi database dengan cepat, kita akan menggunakan layanan mLab. Mudah digunakan, dan untuk sejumlah kecil informasi, gratis.

Buat akun di situs web mLab dan terapkan database MongoDB baru. Untuk melakukan ini, klik tombol Membuat Baru Dalam bab Penerapan MongoDB, di jendela yang muncul, di bagian tersebut Rencana, Pilih Node tunggal. Di daftar Jalur Standar, Pilih Bak pasir dan beri nama databasenya. Selanjutnya, di jendela manajemen basis data, buka tab Pengguna dan tambahkan pengguna database dengan menentukan nama pengguna dan kata sandi.


Pengguna basis data baru

Salin URL kedua dari halaman yang sama - string koneksi database.


URL untuk terhubung ke database

Tambahkan direktori ke root proyek konfigurasi, buat file di dalamnya db.js.

Konfigurasi mkdir cd konfigurasi sentuh db.js
Untuk mengajukan db.js tambahkan yang berikut ini:

Module.exports = (url: URL Anda akan mengarah ke sini);
Jangan lupa untuk menambahkan username dan password pada URL tersebut (bukan yang untuk akun mLab Anda, tapi yang Anda buat untuk database). Jika Anda menghosting proyek di Github, pastikan untuk menyertakan file tersebut .gitignore(seperti ini). Dengan cara ini Anda tidak akan membuat nama dan kata sandi untuk bekerja dengan database menjadi publik.

Sekarang di server.js, Anda dapat menggunakan MongoClient untuk terhubung ke database dan menggabungkan pengaturan aplikasi dalam fungsi yang diteruskan ke sana saat membuat:

// server.js const express = require("ekspres"); const MongoClient = memerlukan("mongodb").MongoClient; const bodyParser = memerlukan("body-parser"); const db = memerlukan("./config/db"); aplikasi const = ekspres(); port konstan = 8000; app.use(bodyParser.urlencoded(( diperpanjang: true ))); MongoClient.connect(db.url, (err, database) => ( jika (err) return console.log(err) require("./app/routes")(aplikasi, database); app.listen(port, ( ) => ( console.log("Kami siaran langsung di " + port); ));
Ini melengkapi persiapan infrastruktur. Mulai sekarang kita akan membahas secara eksklusif tentang jalur.

Menambahkan Catatan ke Database

MongoDB menyimpan data dalam koleksi, yang sesuai dengan namanya. Dalam kasus kami, catatan akan disimpan dalam koleksi, yang, seperti yang Anda duga, akan disebut catatan .

Selama pengaturan klien, diberikan string koneksi database, argumen db. Di kode rute, Anda dapat mengakses database seperti ini:

Db.koleksi("catatan")
Membuat catatan di database sama dengan memanggil perintah sisipkan untuk koleksi catatan:

Const note = ( teks: req.body.body, judul: req.body.title) db.collection("notes").insert(note, (err, results) => ( )
Setelah perintah berhasil diselesaikan (atau setelahnya, karena alasan tertentu, tidak dapat dijalankan), Anda harus mengirim objek catatan yang baru dibuat sebagai respons, atau pesan kesalahan. Ini kodenya note_routes.js, ditambah dengan mempertimbangkan pertimbangan berikut:

// note_routes.js module.exports = function(app, db) ( app.post("/notes", (req, res) => ( const note = ( teks: req.body.body, judul: req.body .title ); db.collection("catatan").insert(catatan, (err, hasil) =>
Cobalah apa yang Anda dapatkan. Kirim permintaan POST dari Tukang Pos (dengan bendera x-www-form-urlencoded), dengan mengatur pada tab Tubuh nilai bidang judul Dan tubuh.

Jawabannya akan terlihat seperti ini:


Berhasil menambahkan catatan ke database

Catatan Bacaan: BACA Rute

Infrastruktur yang kami siapkan di atas cocok untuk semua rute, sehingga kini segalanya berjalan lebih cepat.

Jadi kita akan menanyakan catatan yang baru saja kita buat dengan mengikuti jalurnya localhost:8000/catatan/(id catatan). Dalam kasus kami, jalurnya akan terlihat seperti ini: localhost:8000/catatan/585182bd42ac5b07a9755ea3.

Jika Anda tidak memiliki ID salah satu catatan yang sudah dibuat, Anda dapat melihat database di mLab dan menemukannya di sana, atau membuat catatan baru dan menyalin ID-nya.

Ini adalah tampilannya note_route.js:

// note_routes.js module.exports = function(app, db) ( app.get("/notes/:id", (req, res) => ( )); app.post("/notes", (req , res) => ( const note = ( teks: req.body.body, judul: req.body.title ); db.collection("notes").insert(note, (err, result) => ( if ( err) ( res.send(( "error": "Terjadi kesalahan" )); ) else ( res.send(result.ops); ) ));
Sama seperti sebelumnya, kita akan memanggil beberapa perintah pada kumpulan database catatan. Mari gunakan metode findOne untuk ini.

// note_routes.js module.exports = function(app, db) ( app.get("/notes/:id", (req, res) => ( const detail = ( "_id":<ТУТ БУДЕТ ID>); db.collection("notes").findOne(detail, (err, item) => ( if (err) ( res.send(("error":"Terjadi kesalahan")); ) else ( res.send (barang); )); app.post("/notes", (req, res) => ( const note = ( teks: req.body.body, judul: req.body.title ); db.collection("notes").insert(note , (err, result) => ( if (err) ( res.send(( "error": "Telah terjadi kesalahan" )); ) else ( res.send(result.ops); ) )) ; );
Pengidentifikasi dapat diekstraksi dari parameter URL menggunakan konstruksi req.params.id. Namun, jika Anda cukup menyisipkan baris saja<<>> dari kode di atas, ini tidak akan berhasil.

MongoDB memerlukan ID bukan sebagai string, tetapi sebagai objek khusus. Itu disebut ID Objek.

Inilah yang kami dapatkan setelah beberapa perubahan kecil:

// note_routes.js var ObjectID = memerlukan("mongodb").ObjectID; module.exports = function(app, db) ( app.get("/notes/:id", (req, res) => ( const id = req.params.id; const detail = ( "_id": ObjectID baru (id) ); db.collection("notes").findOne(detail, (err, item) => ( if (err) ( res.send(("error":"Terjadi kesalahan")); ) else ( res.send(item); ) )); app.post("/notes", (req, res) => ( const note = ( teks: req.body.body, judul: req.body .title ) ; db.collection("catatan").insert(catatan, (err, hasil) => ( if (err) ( res.send(( "error": "Telah terjadi kesalahan" )); ) else ( res. kirim(hasil.ops); ) ));
Coba ini dengan salah satu ID catatan yang tersedia di database. Respons di Postman akan terlihat seperti ini:


Permintaan catatan dari database berhasil

Menghapus catatan: HAPUS rute

Menghapus objek pada dasarnya sama dengan mencarinya di database. Hanya saja, alih-alih fungsi findOne, fungsi hapus digunakan. Berikut adalah kode lengkap untuk jalur terkait. Ini menyoroti apa yang berbeda dari kode dalam metode yang ada yang menangani permintaan GET.

// note_routes.js // ... app.delete("/notes/:id", (req, res) => ( const id = req.params.id; const detail = ( "_id": new ObjectID( id) ); db.collection("notes").remove(detail, (err, item) => ( if (err) ( res.send(("error":"Terjadi kesalahan")); ) else ( res.send("Catatan " + id + " dihapus!"); ) )); // ...

Pembaruan catatan: UPDATE rute

Dan inilah rute terakhir. Memproses permintaan PUT pada dasarnya merupakan gabungan dari operasi READ dan CREATE. Pertama Anda perlu menemukan objeknya, lalu memperbaruinya sesuai dengan data yang diterima dalam permintaan. Sekarang, jika Anda menghapus satu-satunya catatan saat menguji cuplikan kode sebelumnya, buat catatan lain.

Berikut catatan update kode rutenya:

// note_routes.js // ... app.put ("/notes/:id", (req, res) => ( const id = req.params.id; const detail = ( "_id": new ObjectID( id) ); const note = ( teks: req.body.body, judul: req.body.title ); err) ( res.send(("error":"Terjadi kesalahan")); ) else ( res.send(note); ) )); // ...
Sekarang catatan apa pun dapat diedit. Berikut tampilannya:


Pembaruan catatan berhasil

Perhatikan kekurangan dalam contoh kita. Jika permintaan PUT tidak berisi isi atau judul catatan, kolom terkait di database akan dihapus begitu saja.

Saya tidak memuat contoh dengan pemeriksaan tambahan. Jika mau, Anda dapat memodifikasi sendiri operasi pembaruan catatan, menambahkan data baru ke database hanya jika permintaan dibuat dengan benar.

Hasil

Anda sekarang memiliki Node API yang berfungsi yang mendukung empat operasi dasar CRUD. Bagian server dari aplikasi dapat, menanggapi permintaan HTTP klien, membuat catatan dalam database, menemukannya, menghapus dan mengeditnya.

Tujuan utama cerita saya adalah untuk memperkenalkan semua orang pada kombinasi Node + Express + MongoDB dan metodologi untuk mengembangkan aplikasi server. Tentu saja, jika hari ini Anda pertama kali mengenal alat-alat ini, untuk lebih memahami semuanya, Anda perlu membaca dokumentasinya. Namun, memahami apa yang terjadi akan memungkinkan Anda dengan cepat mengisi kesenjangan pengetahuan dan mulai mengerjakan proyek Anda sendiri, menggunakan aplikasi yang telah kami kerjakan di sini sebagai titik awal.

Jika Anda memiliki pengalaman bekerja dengan Node.js, Express, dan MongoDB dalam proyek nyata, apakah Anda punya saran untuk pemula? Dan jika Anda baru pertama kali mencoba semua ini, kami tunggu kesan Anda.

$npm instal ekspres

atau, untuk memiliki akses ke perintah ekspres, instal secara global:

$ npm instal -g ekspres

Mulai cepat

Cara termudah untuk memulai Express adalah dengan menjalankan perintah express, yang akan menghasilkan aplikasi:

Membuat aplikasi:

$ npm install -g ekspres $ ekspres /tmp/foo && cd /tmp/foo

Menginstal dependensi:

$npm instal-d

Memulai server:

Membuat server

Untuk membuat instance express.HTTPServer, cukup panggil metode createServer(). Dengan contoh aplikasi kita, kita dapat menentukan rute berdasarkan metode HTTP, dalam contoh ini app.get() .

var aplikasi = memerlukan("ekspres").createServer(); app.get("/", function(req, res)( res.send("halo dunia"); )); aplikasi.mendengarkan(3000);

Membuat server HTTPS

Untuk menginisialisasi express.HTTPSServer , kami melakukan langkah yang sama seperti di atas, tetapi kami juga meneruskan objek opsi yang berisi kunci, sertifikat, dan parameter lain yang dijelaskan dalam dokumentasi modul NodeJS https.

var app = require("express").createServer(( kunci: ... ));

Konfigurasi

Express mendukung lingkungan yang sewenang-wenang, seperti produksi dan pengembangan. Pengembang dapat menggunakan metode konfigurasi() untuk menambahkan fitur yang diperlukan untuk lingkungan tertentu. Ketika konfigurasi() dipanggil tanpa nama lingkungan, konfigurasi tersebut akan diaktifkan di lingkungan mana pun sebelum konfigurasi apa pun yang lingkungannya ditentukan akan diaktifkan.

Pada contoh di bawah ini, kita cukup menggunakan opsi dumpExceptions dan, dalam mode pengembangan, merespons klien dengan jejak tumpukan pengecualian. Di kedua mode, kami menggunakan lapisan methodOverride dan bodyParser. Perhatikan penggunaan app.router , yang memungkinkan rute dipasang - jika tidak, rute tersebut akan dipasang saat pertama kali app.get() , app.post() , dll. dipanggil.

app.configure(function())( app.use(express.methodOverride()); app.use(express.bodyParser()); app.use(app.router); )); app.configure("pengembangan", function())( app.use(express.static(__dirname + "/public")); app.use(express.errorHandler(( dumpExceptions: true, showStack: true ))); ) ); app.configure("produksi", fungsi())( var oneYear = 31557600000; app.use(express.static(__dirname + "/public", ( maxAge: oneYear ))); app.use(express.errorHandler() ) ;

Untuk lingkungan dengan pengaturan serupa, Anda dapat memberikan beberapa nama lingkungan:

app.configure("stage", "prod", function())( // config ));

Untuk pengaturan internal dan sewenang-wenang, Express memiliki metode set(key[, val]) , aktifkan(kunci) , nonaktifkan(kunci) :

app.configure(fungsi () ( app.set("views", __dirname + "/views"); app.set("views"); // => "/absolute/path/to/views" app.enable ("beberapa fitur"); // sama dengan app.set("beberapa fitur", true); app.disable("beberapa fitur"); // sama dengan app.set("beberapa fitur", false) ; .enabled("beberapa fitur") // => false ));

Untuk mengatur lingkungan kita dapat mengatur variabel lingkungan NODE_ENV. Misalnya:

$ NODE_ENV=node produksi app.js

Hal ini sangat penting karena banyak mekanisme caching hanya diaktifkan di lingkungan produksi.

Pengaturan

Di luar kotak Express mendukung pengaturan berikut:

  • home adalah jalur dasar aplikasi, yang digunakan untuk res.redirect() serta dukungan transparan untuk aplikasi yang dipasang.
  • views adalah direktori root dari tampilan. Secara default, folder_saat ini/tampilan
  • view engine - mesin templat default untuk tampilan yang dipanggil tanpa ekstensi file.
  • opsi tampilan - objek yang mencerminkan opsi tampilan global
  • lihat cache - aktifkan tampilan cache (diaktifkan di lingkungan produksi)
  • rute peka huruf besar-kecil - aktifkan rute peka huruf besar-kecil
  • perutean ketat - jika diaktifkan, garis miring tidak lagi diabaikan
  • jsonp callback - izinkan metode res.send() mendukung JSONP secara transparan

Rute

Express menggunakan metode HTTP untuk menyediakan API perutean yang bermakna dan ekspresif. Misalnya, kita ingin pencarian /user/12 menampilkan profil pengguna dengan id=12 . Untuk melakukan ini, kami menentukan rute di bawah ini. Nilai yang terkait dengan bidang bernama tersedia di objek res.params.

app.get("/pengguna/:id", function(req, res)( res.send("pengguna " + req.params.id); ));

Rute hanyalah sebuah string yang dikompilasi menjadi ekspresi reguler di dalam mesin. Misalnya, ketika /user/:id dikompilasi, hasilnya adalah ekspresi reguler seperti ini:

\/pengguna\/([^\/]+)\/?

Anda juga dapat langsung meneruskan ekspresi reguler. Namun karena grup tidak diberi nama dalam ekspresi reguler, grup tersebut dapat dijangkau dalam parameter req.params dengan angka. Jadi grup pertama masuk ke req.params , grup kedua ke req.params , dan seterusnya.

app.get(/^\/users?(?:\/(\d+)(?:\.\.(\d+))?)?/, function(req, res)( res.send(req.params );

Sekarang mari kita ambil curl dan kirim permintaan ke rute di atas:

$ curl http://dev:3000/user $ curl http://dev:3000/users $ curl http://dev:3000/users/1 ["1",null] $ curl http://dev: 3000/pengguna/1..15 ["1","15"]

Berikut adalah beberapa contoh rute dan jalur yang mungkin cocok dengan keduanya:

"/pengguna/:id" /pengguna/12 "/pengguna/:id?" /pengguna/5 /pengguna "/files/*" /files/jquery.js /files/javascripts/jquery.js "/file/*.*" /files/jquery.js /files/javascripts/jquery.js "/ pengguna/:id/:operasi?" /user/1 /user/1/edit "/products.:format" /products.json /products.xml "/products.:format?" /products.json /products.xml /products "/user/:id.:format?" /pengguna/12 /pengguna/12.json

Misalnya, kita dapat POST beberapa JSON dan merespons dengan JSON yang sama menggunakan lapisan bodyParser, yang dapat mengurai permintaan JSON (serta permintaan lainnya) dan menempatkan respons di req.body:

var express = memerlukan("express"), app = express.createServer(); aplikasi.menggunakan(express.bodyParser()); app.post("/", function(req, res) ( res.send(req.body); )); aplikasi.mendengarkan(3000);

Biasanya, kami menggunakan kolom “bodoh” (misalnya, /user/:id), yang tidak memiliki batasan. Namun jika misalnya kita ingin membatasi user ID hanya pada karakter numerik, kita bisa menggunakan /user/:id(+) . Konstruksi ini tidak akan berfungsi jika nilai bidang berisi karakter non-numerik.

Mentransfer kendali ke rute lain

Dengan memanggil argumen ketiga next() , Anda dapat meneruskan kontrol ke rute berikutnya. Jika kecocokan tidak ditemukan, kontrol diteruskan kembali ke Connect dan lapisan terus dipanggil sesuai urutan pengaktifannya menggunakan use() . Beberapa rute yang berbagi jalur yang sama juga berfungsi. Mereka hanya dipanggil satu per satu sampai salah satu dari mereka merespons alih-alih memanggil next() .

app.get("/users/:id?", function(req, res, next) ( var id = req.params.id; if (id) ( // melakukan sesuatu ) else ( next(); ) )) ; app.get("/users", function(req, res) ( // lakukan hal lain ));

Metode app.all() berguna jika Anda ingin menjalankan logika yang sama untuk semua metode HTTP. Di bawah ini kami menggunakan metode ini untuk mengambil pengguna dari database dan menetapkannya ke req.user.

var express = memerlukan("express"), app = express.createServer(); var pengguna = [( nama: "tj" )]; app.all("/user/:id/:op?", function(req, res, next) ( req.user = pengguna; if (req.user) ( next(); ) else ( next(new Error( "tidak dapat menemukan pengguna " + req.params.id)); app.get("/user/:id", function(req, res) ( res.send("viewing " + req.user.name); )); app.get("/user/:id/edit", function(req, res) ( res.send("editing " + req.user.name); )); app.put("/pengguna/:id", function(req, res) ( res.send("memperbarui " + req.user.name); )); app.get("*", function(req, res) ( res.send("apa???", 404); )); aplikasi.mendengarkan(3000);

antar lapisan

Lapisan kerangka Connect dapat diteruskan ke express.createServer() dengan cara yang sama seperti jika server Connect biasa digunakan. Misalnya:

var express = memerlukan("ekspres"); var app = express.createServer(express.logger(), express.bodyParser());

Anda juga dapat menggunakan penggunaan() . Hal ini membuatnya lebih mudah untuk menambahkan lapisan di dalam blok konfigurasi(), yang lebih progresif.

app.use(express.logger(( format: ":metode:url" )));

Biasanya dengan lapisan Connect kita dapat menghubungkan Connect seperti ini:

var koneksi = memerlukan("sambungan"); app.use(hubungkan.logger()); aplikasi.menggunakan(menghubungkan.bodyParser());

Ini sangat tidak nyaman, jadi Express mengekspor ulang lapisan Connect:

app.use(express.logger()); aplikasi.menggunakan(express.bodyParser());

Urutan lapisan itu penting. Jadi, ketika Connect menerima permintaan, lapisan pertama yang ditambahkan melalui createServer() atau use() akan dieksekusi. Itu dipanggil dengan tiga parameter: permintaan, respons, dan fungsi panggilan balik, biasanya dipanggil berikutnya. ketika next() dipanggil, kontrol diteruskan ke lapisan kedua, dan seterusnya. Hal ini penting untuk diperhatikan, karena banyak lapisan yang bergantung satu sama lain. Misalnya, methodOverride() memanggil req.body.method untuk membebani metode HTTP, dan bodyParser() mem-parsing isi permintaan untuk mengisi req.body . Contoh lainnya adalah penguraian cookie dan dukungan sesi - pertama-tama Anda perlu memanggil use() pada cookieParser() , lalu pada session() .

Banyak aplikasi Express mungkin memiliki baris app.use(app.router) . Ini mungkin tampak aneh, tapi ini hanya untuk secara eksplisit menentukan lapisan yang mencakup semua rute yang kita buat. Lapisan ini dapat dimasukkan dalam urutan apa pun, meskipun secara default lapisan ini disertakan di bagian akhir. Dengan mengubah posisinya, Anda dapat mengontrol urutan pelaksanaannya. Misalnya, kita memerlukan pengendali kesalahan yang akan diaktifkan setelah semua lapisan lainnya dan menampilkan pengecualian apa pun yang diteruskan ke lapisan tersebut menggunakan next() . Atau mungkin perlu menurunkan urutan eksekusi lapisan yang menyajikan file statis untuk memungkinkan rute lain mencegat permintaan file tersebut dan, misalnya, menghitung jumlah unduhan, dll. Berikut tampilannya:

app.use(express.logger(...)); app.use(express.bodyParser(...)); app.use(express.cookieParser(...)); app.use(ekspres.sesi(...)); app.use(aplikasi.router); app.use(express.statis(...)); app.use(express.errorHandler(...));

Pertama kita tambahkan logger() - ini akan menggabungkan metode req.end() untuk memberi kita data tingkat respons. Lalu kita parsing badan permintaan (jika ada), lalu cookie, lalu sesi, sehingga req.session sudah ditentukan saat kita sampai ke rute di app.router . Jika, misalnya, permintaan GET ke /javascripts/jquery.js ditangani oleh rute dan kita tidak memanggil next() , maka lapisan static() tidak akan pernah menerima permintaan tersebut. Namun, jika kita menentukan rute seperti yang ditunjukkan di bawah ini, statistik dapat dicatat, menolak unduhan, membebankan biaya unduhan, dll.

var unduhan =(); app.use(aplikasi.router); app.use(express.static(__dirname + "/public")); app.get("/*", function(req, res, next) ( var file = req.params; download = download || 0; download++; next(); ));

Rute lapisan

Rute dapat menggunakan lapisan perutean dengan meneruskan callback (atau array) tambahan ke metode tersebut. Ini berguna jika Anda perlu membatasi akses atau memuat data apa pun sebelum menggunakan rute, dll.

Biasanya, pengambilan data asinkron mungkin terlihat seperti yang ditunjukkan di bawah ini (di sini kita mengambil parameter:id dan memuat data pengguna).

app.get("/user/:id", function(req, res, next) ( loadUser(req.params.id, function(err, user) ( if (err) return next(err); res.send( "Melihat pengguna " + nama pengguna);

Untuk mematuhi prinsip KERING dan meningkatkan keterbacaan kode, Anda dapat mengatur logika tersebut menggunakan lapisan. Seperti yang Anda lihat, dengan mengabstraksi logika menggunakan lapisan, Anda dapat menggunakan kembali lapisan dan membuat kode rute lebih indah.

function loadUser(req, res, next) ( // di sini kita memuat pengguna dari database var pengguna = pengguna; if (pengguna) ( req.user = pengguna; berikutnya(); ) else ( berikutnya(Kesalahan baru("Gagal untuk memuat pengguna " + req.params.id)); ) ) app.get("/user/:id", loadUser, function(req, res) ( res.send("Melihat pengguna " + req.user.name ) ;

Beberapa lapisan perutean dapat ditambahkan, dan lapisan tersebut akan dieksekusi secara berurutan untuk memberikan logika yang berbeda, seperti membatasi akses ke akun pengguna. Pada contoh di bawah, hanya pengguna yang berwenang yang dapat mengedit akunnya.

function andRestrictToSelf(req, res, next) ( req.authenticatedUser.id == req.user.id ? next() : next(new Error("Unauthorized")); ) app.get("/user/:id/ edit", loadUser, andRestrictToSelf, function(req, res) ( res.send("Mengedit pengguna " + req.user.name); ));

Menyadari bahwa lapisan hanyalah fungsi, Anda dapat menulis fungsi yang mengembalikan lapisan (untuk memberikan solusi yang lebih ekspresif dan fleksibel), seperti yang ditunjukkan di bawah ini.

function andRestrictTo(role) ( return function(req, res, next) ( req.authenticatedUser.role == role ? next() : next(new Error("Unauthorized")); ) ) app.del("/user/ :id", loadUser, andRestrictTo("admin"), function(req, res) ( res.send("Pengguna yang dihapus " + req.user.name); ));

“Tumpukan” lapisan yang sering digunakan dapat diteruskan sebagai larik dengan kedalaman dan struktur pohon yang berubah-ubah (akan diterapkan secara rekursif):

var a = , b = , semua = ; app.get("/foo", a, function() ()); app.mendapatkan("/bar", a, fungsi() ()); app.get("/", a, middleware3, middleware4, function() ()); aplikasi.mendapatkan("/", a, b, fungsi() ()); app.get("/", semua, fungsi() ());

Contoh selengkapnya dapat dilihat di repositori.

Ada kalanya Anda perlu melewati lapisan rute yang tersisa di tumpukan, namun terus mengeksekusi rute berikutnya. Untuk melakukan ini, panggil next() dengan argumen rute: next("route") . Jika tidak ada rute tersisa untuk dieksekusi, Express akan merespons dengan kesalahan 404 Not Found.

metode HTTP

Kami telah menggunakan app.get() berkali-kali, tetapi Express juga menyediakan metode HTTP lainnya - app.post() , app.del() , dll.

Kasus penggunaan POST yang paling umum adalah saat mengirimkan formulir. Pada contoh di bawah ini kita hanya membuat form HTML. Dan kemudian kontrol akan ditransfer ke rute yang akan kita tentukan pada contoh berikutnya.

Secara default, Express tidak tahu apa yang harus dilakukan dengan isi permintaan, jadi kita harus menambahkan lapisan bodyParser() yang akan mengurai isi permintaan yang dikodekan dalam application/x-www-form-urlencoded atau application/json dan meletakkan parsingnya menghasilkan req .body . Untuk melakukan ini kita harus mengatakan use() seperti di bawah ini:

aplikasi.menggunakan(express.bodyParser());

Sekarang rute di bawah ini akan mengakses objek req.body.user, yang akan memiliki properti nama dan email:

app.post("/", function(req, res) ( console.log(req.body.user); res.redirect("back"); ));

Jika formulir menggunakan metode seperti PUT, Anda dapat menggunakan input tersembunyi yang disebut _method, yang memungkinkan Anda mengubah metode HTTP. Untuk mencapai hal ini, pertama-tama kita harus mengaktifkan lapisan methodOverride(), yang akan ditempatkan setelah bodyParser(), yang akan memungkinkannya menggunakan req.body yang berisi bidang formulir yang dikirimkan.

aplikasi.menggunakan(express.bodyParser()); aplikasi.penggunaan(express.methodOverride());

Lapisan ini tidak diaktifkan secara default, karena Express belum tentu memiliki fungsionalitas penuh. Tergantung pada kebutuhan aplikasi, Anda mungkin tidak perlu menggunakannya. Kemudian metode PUT dan DELETE akan tetap tersedia, tetapi secara langsung. Pada saat yang sama, methodOverride adalah solusi terbaik untuk formulir HTML. Di bawah ini adalah contoh penggunaan metode PUT:

app.put("/", function() ( console.log(req.body.user); res.redirect("back"); ));

Pemrosesan kesalahan

Express memiliki metode app.error() yang menerima pengecualian apa pun yang diberikan oleh rute atau diteruskan sebagai next(err) . Di bawah ini adalah contoh cara menyajikan beberapa halaman menggunakan pengecualian NotFound buatan sendiri:

function NotFound(pesan) ( this.name = "NotFound"; Error.call(ini, pesan); Error.captureStackTrace(this, argument.callee); ) NotFound.prototype.__proto__ = Error.prototype; app.get("/404", function(req, res) ( melempar NotFound baru; )); app.get("/500", function(req, res) ( throw new Error("keyboard cat!"); ));

Anda dapat memanggil app.error() beberapa kali seperti yang ditunjukkan di bawah ini. Di sini kita memeriksa instanceof NotFound dan menampilkan halaman 404, atau meneruskan kontrol ke penangan kesalahan berikutnya.

Perlu diperhatikan bahwa penangan ini dapat ditentukan di mana saja, karena penangan tersebut akan tetap ditempatkan di bawah penangan rute di listening() . Hal ini memungkinkan mereka untuk didefinisikan di dalam blok konfigurasi(), sehingga pengecualian dapat ditangani secara berbeda tergantung pada lingkungan saat ini.

app.error(function(err, req, res, next) ( if (err instanceof NotFound) ( res.render("404.jade"); ) else ( next(err); ) ));

Demi kesederhanaan, kami berasumsi di sini bahwa semua kesalahan memiliki kode 500, tetapi Anda dapat mengubahnya sesuai keinginan. Misalnya, ketika Node melakukan operasi sistem file, kita bisa mendapatkan objek kesalahan dengan bidang error.code = ENOENT, yang berarti “file atau direktori tidak ditemukan”, kita dapat menggunakan ini dalam penangan kesalahan dan menampilkan halaman yang sesuai.

app.error(fungsi(err, req, res) ( res.render("500.jade", ( error: err )); ));

Aplikasi juga dapat menggunakan lapisan errorHander Connect untuk menangani pengecualian. Misalnya, jika Anda perlu menampilkan pengecualian di stderr di lingkungan pengembangan, Anda dapat melakukan ini:

app.use(express.errorHandler(( dumpExceptions: true )));

Selain itu, selama pengembangan, kita mungkin memerlukan halaman HTML keren yang menampilkan pengecualian yang dilempar atau dilempar. Dalam hal ini, Anda perlu menyetel showStack ke true:

app.use(express.errorHandler(( showStack: true, dumpExceptions: true )));

Lapisan errorHandler juga merespons dalam JSON jika header Accept: application/json diteruskan oleh klien, yang berguna untuk mengembangkan aplikasi AJAX.

Parameter rute pra-pemrosesan

Parameter rute pra-pemrosesan dapat meningkatkan keterbacaan aplikasi secara signifikan melalui pemuatan data eksplisit dan validasi URL permintaan. Misalnya, jika Anda terus-menerus mengambil beberapa data untuk kueri tertentu (misalnya memuat data pengguna untuk /user/:id), Anda dapat melakukan hal seperti ini:

app.get("/user/:userId", function(req, res, next) ( User.get(req.params.userId, function(err, user) ( if (err) return next(err); res. send("pengguna "+namapengguna));

Dengan prasyarat, kita bisa melampirkan fungsi panggilan balik ke parameter kueri kita yang akan melakukan validasi, membatasi akses, atau bahkan memuat data dari database. Pada contoh di bawah, kita memanggil app.param() dengan nama parameter yang ingin kita lampirkan callbacknya. Seperti yang Anda lihat, kami menerima argumen id, yang berisi nama bidang. Dengan cara ini kita memuat objek pengguna dan melakukan penanganan kesalahan biasa dan panggilan sederhana ke next() untuk meneruskan kontrol ke prasyarat berikutnya atau pengendali rute.

app.param("userId", function(req, res, next, id) ( User.get(id, function(err, user) ( if (err) return next(err); if (!user) return next( Kesalahan baru("gagal menemukan pengguna")); req.pengguna = pengguna();

Langkah-langkah di atas, sebagaimana telah disebutkan, secara signifikan meningkatkan keterbacaan kode dan memudahkan penggunaan logika yang sama di berbagai tempat dalam aplikasi:

app.get("/user/:userId", function(req, res) ( res.send("user " + req.user.name); ));

Merender Tampilan

Lihat nama file ikuti skema (nama). (engine), dimana (engine) adalah nama modul template engine yang harus dihubungkan. Misalnya, tampilan layout.ejs memberitahu sistem tampilan untuk melakukan require("ejs") . Untuk berintegrasi dengan Express, modul yang dapat dimuat harus mengekspor metode, exports.compile(str, options) , dan mengembalikan fungsi. Untuk mengubah perilaku ini, Anda dapat menggunakan metode app.register() - metode ini memungkinkan Anda mengaitkan ekstensi file dengan mesin tertentu. Misalnya, Anda dapat membuat foo.html dirender oleh mesin ya.

Di bawah ini adalah contoh penggunaan Giok untuk merender index.html . Dan karena kita tidak menggunakan layout:false , konten yang dirender dari tampilan index.jade akan diteruskan sebagai variabel body lokal ke tampilan layout.jade.

app.get("/", function(req, res) ( res.render("index.jade", ( judul: "Situs Saya" )); ));

Menyiapkan mesin tampilan memungkinkan Anda menentukan mesin templat default. Jadi, misalnya saat menggunakan Jade Anda bisa melakukan ini:

app.set("lihat mesin", "giok");

yang akan memungkinkan kita untuk merender seperti ini:

res.render("indeks");

Tapi tidak seperti ini:

res.render("index.jade");

Ketika mesin templat dipasang melalui mesin tampilan, ekstensi file tidak diperlukan. Namun kita tetap bisa menggunakan beberapa template engine sekaligus:

res.render("halaman lain.ejs");

Express juga memiliki pengaturan opsi tampilan yang akan diterapkan setiap kali tampilan dirender. Misalnya, jika Anda jarang menggunakan layout, Anda bisa menulisnya seperti ini:

app.set("opsi tampilan", ( tata letak: false ));

Yang kemudian dapat kelebihan beban jika perlu dalam panggilan ke res.render() :

res.render("tampilan saya.ejs", ( tata letak: true ));

Saat Anda memerlukan tata letak yang berbeda, Anda juga dapat menentukan jalurnya. Misalnya, jika mesin tampilan kita disetel ke giok dan file tata letaknya dipanggil ./views/mylayout.jade , kita cukup meneruskan:

res.render("halaman", ( tata letak: "tata letak saya" ));

Jika tidak, Anda dapat meneruskan ekstensi file:

res.render("halaman", ( tata letak: "mylayout.jade" ));

Jalur juga bisa bersifat absolut:

res.render("halaman", ( tata letak: __dirname + "/../../mylayout.jade" ));

Contoh yang baik adalah menentukan tag mesin pembuka dan penutup non-standar ya:

app.set("opsi tampilan", ( buka: "((", tutup: "))" ));

Lihat Fragmen

Sistem tampilan Ekspres memiliki dukungan bawaan untuk fragmen dan koleksi, semacam tampilan mini. Misalnya, daripada mengulang tampilan untuk menampilkan daftar komentar, Anda cukup menggunakan fragmen koleksi:

parsial("komentar", (koleksi: komentar));

Jika opsi lain atau variabel lokal tidak diperlukan, Anda dapat melewati objek dan meneruskan array data. Contoh di bawah ini setara dengan contoh sebelumnya:

parsial("komentar",komentar);

Saat menggunakan koleksi, kami memiliki beberapa variabel lokal “ajaib”:

  • firstInCollection - benar jika ini adalah objek pertama
  • indexInCollection - indeks objek dalam koleksi
  • lastInCollection - benar jika ini adalah objek terakhir
  • collectionLength - panjang koleksi

Variabel lokal yang diteruskan atau dihasilkan akan diutamakan, namun variabel lokal yang diteruskan ke tampilan induk juga tersedia untuk tampilan anak. Jadi misalnya, jika kita merender tampilan menggunakan parsial("blog/post", post) dan menghasilkan variabel lokal post , dan tampilan yang memanggil fungsi ini memiliki variabel lokal user , maka user juga akan terlihat di blog /tampilan posting.

Lihat res.partial() untuk dokumentasi selengkapnya.

Catatan: Gunakan koleksi dengan hati-hati, karena merender array yang terdiri dari 100 elemen berarti merender 100 tampilan. Untuk koleksi sederhana, lebih baik mengulang tampilan daripada menggunakan koleksi. Dengan cara ini bebannya akan lebih sedikit.

Cari tampilan

Tampilan dicari relatif terhadap tampilan induk. Misalnya, jika kita memiliki tampilan views/user/list.jade dan di dalamnya kita memanggil parsial("edit") , sistem akan mencoba memuat tampilan views/user/edit.jade , sedangkan parsial("../ messages") akan menghasilkan pengunduhan views/messages.jade

Sistem tampilan juga memungkinkan Anda membuat file indeks. Misalnya, kita dapat memanggil res.render("users") dan ini dapat memuat views/users.jade dan views/users/index.jade .

Anda juga dapat menggunakan file indeks dari tampilan di direktori yang sama. Jadi memanggil parsial("pengguna") dapat mengakses tampilan ../users/index alih-alih memanggil parsial("index") .

Mesin templat

Berikut adalah beberapa mesin template yang biasa digunakan dengan Express:

  • E.J.S.- JavaScript bawaan
  • KopiKup- berbasis templat Skrip Kopi
  • Templat jQuery untuk Node

Dukungan sesi

Dukungan sesi dapat diaktifkan menggunakan lapisan sesi Connect. Juga untuk ini kita memerlukan lapisan cookieParser di atasnya, yang akan mengurai cookie dan menempatkannya di req.cookies.

app.use(express.cookieParser()); app.use(express.session(( rahasia: "keyboard kucing" )));

Secara default, lapisan sesi menggunakan penyimpanan dalam memori Connect, namun ada banyak solusi lainnya. Misalnya sambungkan-redis mendukung penyimpanan sesi di ulang. Berikut cara menggunakannya:

var RedisStore = memerlukan("connect-redis")(ekspres); app.use(express.cookieParser()); app.use(express.session(( rahasia: "keyboard cat", toko: RedisStore baru )));

Sekarang properti req.session dan req.sessionStore akan tersedia dari semua rute dan lapisan berikutnya. Properti req.session secara otomatis disimpan setelah respons. Berikut cara mengatur keranjang Anda:

var RedisStore = memerlukan("connect-redis")(ekspres); aplikasi.menggunakan(express.bodyParser()); app.use(express.cookieParser()); app.use(express.session(( rahasia: "keyboard cat", toko: RedisStore baru ))); app.post("/add-to-cart", function(req, res) ( // katakanlah kita meneruskan beberapa objek dari formulir // gunakan bodyParser() untuk ini var items = req.body.items; req. sesi.item = item; res.redirect("kembali" )); app.get("/add-to-cart", function(req, res) ( // Saat kita mengalihkan ke GET /add-to-cart // kita dapat memeriksa req.session.items && req.session.items . length // untuk mencetak pesan kita if (req.session.items && req.session.items.length) ( req.flash("info", "Anda memiliki %s item di keranjang Anda", req.session.items.length ); res.render("keranjang belanja");

Objek req.session juga memiliki metode Session.touch() , Session.destroy() , Session.regenerate() untuk memanipulasi sesi. Untuk informasi lebih lengkap, lihat dokumentasi Connect Session.

Panduan Migrasi

Pengembang yang pernah bekerja dengan Express 1.x dapat merujuk ke panduan migrasi agar aplikasi mereka dapat berfungsi dengan Express 2.x, Connect 1.x, dan Node 0.4.x.

Meminta

req.header(kunci[, Nilai default])

Dapatkan header permintaan kunci (tidak peka huruf besar-kecil) dengan DefaultValue default opsional:

req.header("Tuan Rumah"); req.header("host"); req.header("Terima", "*/*");

Header Referrer dan Referer adalah kasus khusus; kedua konstruksi tersebut akan berfungsi:

// mengirimkan header "Referrer: http://google.com" req.header("Referer"); // => "http://google.com" req.header("Referensi"); // => "http://google.com"

req.accepts(ketik)

Memeriksa apakah header Accept diteruskan dan apakah cocok dengan tipe yang diberikan.

Jika header Terima tidak ada, nilai true dikembalikan. Jika tidak, tipenya cocok dan kemudian subtipenya diperiksa. Dimungkinkan untuk meneruskan "html" yang dikonversi secara internal menjadi "teks/html" menggunakan tabel pencarian MIME.

// Terima: teks/html req.accepts("html"); // => benar // Terima: teks/*; application/json req.accepts("html"); req.accepts("teks/html"); req.accepts("teks/polos"); req.accepts("aplikasi/json"); // => true req.accepts("gambar/png"); req.accepts("png"); // => salah

req.is(ketik)

Memeriksa permintaan masuk untuk mengetahui keberadaan header Tipe Konten dan cocok dengan tipe MIME yang ditentukan.

// Biarkan Tipe Konten: teks/html; charset=utf-8 req.is("html"); req.is("teks/html"); // => true // Biarkan Tipe Konten sekarang menjadi application/json req.is("json"); req.is("aplikasi/json"); // => true req.is("html"); // => salah

Di Express, Anda dapat mendaftarkan panggilan balik Anda sendiri untuk berbagai pemeriksaan permintaan. Sebagai contoh, katakanlah kita perlu melakukan pemeriksaan yang bagus untuk melihat apakah permintaan yang masuk berupa gambar. Untuk melakukan ini, Anda dapat mendaftarkan panggilan balik "gambar":

app.is("sebuah gambar", function(req) ( return 0 == req.headers["content-type"].indexOf("image"); ));

Sekarang Anda dapat menggunakannya di dalam penangan rute untuk memeriksa Tipe Konten dari formulir "image/jpeg", "image/png", dll.

app.post("/image/upload", function(req, res, next) ( if (req.is("an image")) ( // melakukan tindakan tertentu ) else ( next(); ) ));

Jangan lupa bahwa metode ini tidak hanya berlaku untuk Tipe Konten - Anda dapat melakukan pemeriksaan apa pun.

Anda juga dapat menggunakan karakter wildcard. Ini akan menyederhanakan contoh gambar kita. Di sini kami hanya akan memeriksa jenisnya:

req.is("gambar/*");

Kami juga dapat memeriksa subtipe seperti yang ditunjukkan di bawah ini. Di sini pemeriksaan akan mengembalikan nilai true dalam kasus "application/json" dan "text/json" .

req.is("*/json");

req.param(nama[, default])

Mengembalikan nilai parameter name atau - jika tidak ada - default .

Memeriksa parameter rute (req.params), misalnya /user/:id

Memeriksa parameter string kueri (req.query), misalnya, ?id=12

Memeriksa parameter urlencoded dari badan permintaan (req.body), misalnya, id=12

Untuk menerima parameter badan permintaan yang diberi kode urlen, objek req.body harus ada. Untuk melakukan ini, aktifkan lapisan bodyParser().

req.get(bidang, param)

Mendapatkan parameter bidang header. Standarnya adalah string kosong.

req.get("disposisi konten", "nama file"); // => "sesuatu.png" req.get("Tipe Konten", "batas"); // => "--foo-bar-baz"

req.flash(ketik[, pesan])

Mengantri pesan popup.

req.flash("info", "email terkirim"); req.flash("kesalahan", "pengiriman email gagal"); req.flash("info", "email terkirim ulang"); // => 2 req.flash("info"); // => ["email terkirim", "email terkirim ulang"] req.flash("info"); // => req.flash(); // => ( kesalahan: ["pengiriman email gagal"], info: )

Pesan pop-up juga dapat menggunakan format string. String default "%s" tersedia:

req.flash("info", "pengiriman email ke _%s_ dari _%s_ gagal.", toUser, fromUser);

req.isXMLHttpRequest

Juga disingkat req.xhr. Periksa header X-Requested-With untuk melihat apakah permintaan dibuat menggunakan XMLHttpRequest:

req.xhr req.isXMLHttpRequest

Tanggapan

res.header(kunci[, val])

Mendapatkan atau menyetel header respons.

res.header("Panjang Konten"); // => res.header tidak terdefinisi("Panjang Konten", 123); // => 123 res.header("Panjang Konten"); // => 123

res.charset

Menyetel pengkodean header Tipe Konten berikut. Misalnya, res.send() dan res.render() akan default ke "utf8" dan kita dapat secara eksplisit mengatur pengkodean sebelum merender template:

res.charset = "ISO-8859-1"; res.render("pengguna");

atau sebelum membalas dengan res.send() :

res.charset = "ISO-8859-1"; res.kirim(str);

atau menggunakan res.end() bawaan Node :

res.charset = "ISO-8859-1"; res.header("Tipe Konten", "teks/polos"); res.end(str);

res.contentType(tipe)

Menyetel header respons Tipe Konten.

var nama file = "jalur/ke/gambar.png"; res.contentType(nama file); // Tipe Konten sekarang menjadi "gambar/png"

Anda juga dapat mengatur Tipe Konten dengan string berikut:

res.contentType("aplikasi/json");

Atau hanya ekstensi file (tanpa titik di depannya):

res.contentType("json");

res.lampiran()

Menyetel header respons Content-Disposition ke "attachment" . Secara opsional, nama file dapat diberikan.

res.attachment("jalur/ke/saya/gambar.png");

res.sendfile(jalur[, opsi[, panggilan balik]])

Digunakan di res.download() untuk mentransfer file arbitrer.

res.sendfile("jalur/ke/file saya");

Metode ini mengambil parameter panggilan balik opsional, yang dipanggil jika transfer file gagal atau berhasil. Secara default, next(err) dipanggil, tetapi jika panggilan balik diteruskan, maka ini harus dilakukan secara eksplisit, atau menangani kesalahannya.

res.sendfile(path, function(err) ( if (err) ( next(err); ) else ( console.log("transferred %s", path); ) ));

Anda juga dapat meneruskan opsi ke panggilan fs.createReadStream(). Misalnya, untuk mengubah ukuran buffer:

res.sendfile(jalur, ( bufferSize: 1024 ), function(err) ( // memproses... ));

res.download(file[, nama file[, panggilan balik[, panggilan balik2]]])

Unggah file ini sebagai lampiran (Anda dapat menentukan nama file alternatif opsional).

res.download('jalur/ke/gambar.png');

res.download('jalur/ke/gambar.png', 'foo.png');

Ini setara dengan berikut ini:

res.lampiran(file); res.sendfile(file);

Secara opsional, Anda dapat menentukan callback sebagai argumen kedua atau ketiga untuk res.sendfile() . Di dalamnya, Anda dapat merespons seolah-olah header belum dikirimkan.

res.download(jalur, "pengeluaran.doc", function(err) ( // memproses... ));

Anda juga dapat meneruskan panggilan balik kedua - callback2 . Ini menangani kesalahan terkait koneksi. Namun, mereka tidak boleh mencoba mengirimkan tanggapan.

res.download(path, function(err) ( // kesalahan atau penghentian), function(err) ( // kesalahan koneksi ));

res.send(body|status[, header|status[, status]])

Metode res.send() adalah fasilitas respons tingkat tinggi yang memungkinkan Anda meneruskan objek (untuk respons JSON), string (untuk respons HTML), instance Buffer, atau bilangan bulat yang menentukan kode status (404, 500, dll. .) . Begini cara penggunaannya:

res.kirim(); // 204 kirim ulang(Buffer baru("wahoo")); res.send(( beberapa: "json" )); res.kirim(""); res.send("Maaf, tidak dapat menemukannya", 404); res.send("teks", ( "Jenis Konten": "teks/polos" ), 201); kirim ulang(404);

Secara default, header Tipe Konten diatur secara otomatis. Namun, jika disetel secara manual secara eksplisit di res.send() atau sebelum menggunakan res.header() , atau menggunakan res.contentType() , maka tidak akan disetel secara otomatis.

Perhatikan bahwa metode ini mengakhiri respons (mirip dengan res.end()), jadi jika Anda perlu menghasilkan beberapa respons, atau satu aliran, Anda perlu menggunakan res.write() .

res.json(obj[, header|status[, status]])

Mengirimkan respons JSON dengan header opsional dan kode status. Metode ini ideal untuk mengatur API JSON, tetapi JSON juga dapat dikirim menggunakan res.send(obj) (yang tidak ideal jika Anda hanya ingin mengirim string yang dikodekan JSON, karena res.send(string) akan mengirim HTML)

res.json(null); res.json(( pengguna: "tj" )); res.json("penjaga!", 500); res.json("Tidak ada yang ditemukan", 404);

res.redirect(url[, status])

Pengalihan ke URL yang ditentukan. Kode status default adalah 302.

res.redirect("/", 301); res.redirect("/akun"); res.redirect("http://google.com"); res.redirect("beranda"); res.redirect("kembali");

Express mendukung pintasan untuk pengalihan - yang default adalah "back" dan "home" . Dalam hal ini, "kembali" mengalihkan ke URL yang ditentukan di header Referrer (atau Referer), dan "home" menggunakan pengaturan "home" (default "/").

res.cookie(nama, val[, pilihan])

Menetapkan nilai nama cookie yang diberi nama menjadi val . Opsi: httpOnly, aman, kedaluwarsa, dll. Opsi jalur defaultnya adalah nilai yang ditetapkan dalam pengaturan "home", biasanya "/" .

// "Ingat saya" selama 15 menit res.cookie("ingat saya", "ya", ( kadaluwarsa: Tanggal baru(Tanggal.sekarang() + 900000), httpOnly: true ));

Properti maxAge dapat diatur agar kedaluwarsa relatif terhadap Date.now() dalam milidetik. Jadi contoh kita di atas sekarang dapat ditulis ulang menjadi:

res.cookie("ingat saya", "ya", ( maxAge: 900000 ));

Untuk mengurai cookie yang masuk, gunakan lapisan cookieParser, yang menghasilkan objek req.cookies:

app.use(express.cookieParser()); app.get("/", function(req, res) ( // gunakan req.cookies.rememberme ));

res.clearCookie(nama[, opsi])

Kami menghapus cookie bernama name , menetapkan parameter expired tanggal di masa lalu. Opsinya sama seperti untuk res.cookie() , jalurnya juga default ke pengaturan "home".

res.clearCookie("ingat saya");

res.render(lihat[, pilihan[, fn]])

Merender tampilan dengan opsi yang diberikan dan panggilan balik fn opsional. Ketika fn diberikan, respons ke klien tidak otomatis, sebaliknya respons teks/html dibuat dengan kode 200 .

Opsi yang diteruskan juga merupakan variabel tampilan lokal. Misalnya, jika kita ingin meneruskan variabel pengguna dan menonaktifkan tata letak, kita melakukannya dalam satu objek:

var pengguna = ( nama: "tj" ); res.render("index", ( layout: false, pengguna: pengguna ));

Objek opsi juga digunakan untuk meneruskan opsi. Misalnya, jika Anda meneruskan properti status, properti tersebut tidak hanya tersedia untuk tampilan, namun juga menyetel kode status respons. Ini juga berguna jika mesin templat menerima opsi tertentu, seperti debug atau kompres. Di bawah ini adalah contoh bagaimana Anda dapat merender halaman kesalahan - status diteruskan di sini untuk menampilkannya dan menyetel kode status res.statusCode .

res.render("kesalahan", ( status: 500, pesan: "Kesalahan Server Internal" ));

res.partial(lihat[, opsi])

Merender sebuah fragmen dengan opsi yang diberikan. Metode ini selalu dapat diakses dari tampilan sebagai variabel lokal.

  • objek - objek yang diteruskan ke tampilan
  • seperti nama variabel yang akan mewakili objek objek atau setiap elemen koleksi yang diteruskan ke tampilan. Defaultnya adalah nama tampilan.
    • sebagai: "sesuatu" - akan menambahkan sesuatu variabel lokal
    • sebagai: ini - akan menggunakan elemen koleksi sebagai konteks tampilan (ini)
    • sebagai: global - akan menggabungkan properti elemen koleksi dan variabel tampilan lokal
    • koleksi - serangkaian objek. Namanya berasal dari nama pemandangannya. Misalnya video.html akan memiliki objek video di dalamnya.

Konstruksi berikut ini setara satu sama lain dan nama koleksi yang diteruskan ke fragmen akan selalu "movie" .

parsial("theatre/movie.jade", (koleksi: film )); parsial("teater/film.jade", film); parsial("movie.jade", (koleksi: film )); parsial("film.jade", film); parsial("film", film); // Di dalam tampilan: moovie.director

Untuk mengubah nama variabel lokal dari "film" menjadi "video" Anda dapat menggunakan opsi as:

parsial("film", (koleksi: film, sebagai: "video" )); // Di dalam tampilan: video.director

Kita juga bisa menjadikan movie nilai this di dalam view kita sehingga alih-alih movie.director kita bisa merujuk ke this.director .

parsial("film", (koleksi: film, seperti: ini )); // Di dalam tampilan: this.director

Solusi alternatifnya adalah dengan memperluas properti elemen koleksi menjadi variabel pseudo-global (sebenarnya lokal) menggunakan sebagai: global , yang merupakan gula sintaksis:

parsial("film", (koleksi: film, sebagai: global )); // Di dalam tampilan: direktur

Logika yang sama berlaku tidak hanya pada koleksi, tetapi juga pada objek di dalam tampilan fragmen:

parsial("film", ( objek: film, sebagai: ini )); // Di dalam tampilan: this.director parsial("film", ( objek: film, sebagai: global )); // Di dalam tampilan: sutradara parsial("film", ( objek: film, sebagai: "video" )); // Di dalam tampilan: video.director parsial("film", ( objek: film )); // sutradara film

Jika argumen kedua adalah non-koleksi (tanpa .length), argumen tersebut diperlakukan sebagai objek. Dalam hal ini, nama variabel lokal untuk objek ini dibentuk dari nama tampilan.

var movie = new Movie("Nightmare Before Christmas", "Tim Burton") parsial("movie", movie) // => Di dalam tampilan: movie.director

Pengecualian terhadap aturan ini adalah ketika objek sederhana ("()" atau "Objek baru") diteruskan, maka objek tersebut dianggap sebagai objek lokal dan tidak dapat diakses berdasarkan namanya dalam tampilan fragmen. Misalnya, dalam contoh berikut Anda mengharapkan adanya variabel lokal "movie" , namun karena ini adalah objek sederhana, variabel lokalnya sudah berupa "director" dan "title" , yaitu propertinya:

var movie = ( judul: "Mimpi Buruk Sebelum Natal", sutradara: "Tim Burton" ); parsial("film", film)

Untuk kasus seperti ini, ketika Anda perlu meneruskan objek sederhana, cukup tetapkan objek tersebut ke beberapa properti, atau gunakan properti objek, yang akan mewarisi nama objek dari nama file. Contoh-contoh yang tercantum di bawah ini setara:

parsial("film", ( penduduk setempat: ( film: film )) parsial("film", ( film: film )) parsial("film", ( objek: film ))

API yang sama dapat digunakan dari suatu rute sehingga Anda dapat merespons dengan fragmen HTML melalui AJAX atau WebSockets, misalnya Anda dapat merender kumpulan pengguna langsung dari rute tersebut:

app.get("/users", function(req, res) ( if (req.xhr) ( // mengirimkan respons setiap pengguna dari koleksi // meneruskan ke tampilan "pengguna" res.partial("pengguna", pengguna) ; ) else ( // merespons dengan tata letak lengkap dengan halaman daftar pengguna // templat yang membuat parsial("pengguna", pengguna) // dan menambahkan semacam antarmuka res.render("pengguna", ( pengguna: pengguna ) );

res.lokal(nama[, val])

Dapatkan atau setel variabel lokal yang ditentukan. Variabel lokal dalam hal ini mengacu pada variabel yang diteruskan ke metode rendering tampilan, seperti res.render() .

app.all("/movie/:id", function(req, res, next) ( Movie.get(req.params.id, function(err, movie) ( // Membuat tugas res.locals.movie = movie res .local("film", film )); app.get("/movie/:id", function(req, res) ( // variabel lokal movie sudah ada // tapi kita bisa menambahkannya jika diperlukan res.render("movie", ( displayReviews: true ) ); ));

res.lokal(obj)

Tetapkan beberapa variabel lokal menggunakan objek obj yang diberikan. Berikut ini setara:

res.local("foo",bar); res.lokal("bar", baz); res.locals(( foo: bar, bar, baz ));

pelayan

aplikasi.set(nama[, val])

Tetapkan pengaturan nama aplikasi ke val , atau dapatkan nilai pengaturan nama jika val tidak ada:

app.set("tampilan", __dirname + "/tampilan"); app.set("tampilan"); // => ...jalur...

Anda juga dapat mengakses pengaturan melalui pengaturan aplikasi:

app.settings.views // => ...jalur...

app.enable (nama)

Menyetel pengaturan nama ke benar:

app.enable("beberapa pengaturan sewenang-wenang"); app.set("beberapa pengaturan sewenang-wenang"); // => true app.enabled("beberapa pengaturan sewenang-wenang"); // => benar

app.enabled (nama)

Memeriksa apakah pengaturan nama sudah benar:

app.enabled("lihat cache"); // => false app.enable("lihat cache"); app.enabled("lihat cache"); // => benar

app.disable (nama)

Setel pengaturan nama ke false:

app.disable("beberapa pengaturan"); app.set("beberapa pengaturan"); // => false app.disabled("beberapa pengaturan"); // => salah

app.disabled (nama)

Memeriksa apakah pengaturan nama salah:

app.enable("lihat cache"); app.disabled("lihat cache"); // => false app.disable("lihat cache"); app.disabled("lihat cache"); // => benar

app.configure(env|fungsi[, fungsi])

Menentukan panggilan balik fungsi panggilan balik untuk lingkungan env (atau untuk semua lingkungan):

app.configure(function() ( // berjalan untuk semua lingkungan )); app.configure("development", function() ( // hanya dijalankan untuk lingkungan "pengembangan"));

app.redirect(nama, val)

Untuk res.redirect() kita dapat mendefinisikan shortcut (dalam lingkup aplikasi) seperti di bawah ini:

app.redirect("google", "http://google.com");

Sekarang di rute yang bisa kita hubungi:

res.redirect("google");

Anda juga dapat melakukan singkatan dinamis:

app.redirect("comments", function(req, res) ( return "/post/" + req.params.id + "/comments"; ));

Sekarang Anda dapat melakukan hal berikut dan pengalihan akan dibuat secara dinamis sesuai dengan konteks permintaan. Jika kita memanggil rute dengan GET /post/12, pengalihan kita akan menjadi /post/12/comments.

app.get("/post/:id", function(req, res) ( res.redirect("comments"); ));

Jika aplikasi dipasang, res.redirect() akan memperhitungkan titik pemasangan aplikasi. Misalnya, jika aplikasi blog dipasang di /blog , contoh berikut akan dialihkan ke /blog/posts:

res.redirect("/postingan");

aplikasi.kesalahan(fungsi)

Menambahkan fungsi penangan kesalahan yang parameter pertamanya akan menerima semua pengecualian, seperti yang ditunjukkan di bawah ini. Perhatikan bahwa dimungkinkan untuk menyetel beberapa penangan kesalahan dengan memanggil metode ini beberapa kali, namun metode tersebut harus memanggil next() jika tidak ingin menangani pengecualian itu sendiri:

app.error(fungsi(err, req, res, next) ( res.send(err.message, 500); ));

app.helpers(obj)

Mendaftarkan pembantu tampilan statis.

app.helpers(( nama: fungsi(pertama, terakhir) ( kembalikan dulu + ", " + terakhir ), Nama Depan: "tj", Nama Belakang: "holowaychuk" ));

Tampilan kita sekarang dapat menggunakan variabel firstName dan lastName serta fungsi name().

<%= name(firstName, lastName) %>

Express juga menyediakan beberapa variabel lokal secara default:

  • pengaturan - objek pengaturan aplikasi
  • layout(path) menentukan tata letak langsung dari dalam tampilan

Metode ini alias app.locals() .

app.dynamicHelpers(obj) (#app.dynamic-helpers)

Mendaftarkan pembantu tampilan dinamis. Pembantu tampilan dinamis hanyalah fungsi yang mengambil res , req dan dieksekusi dalam konteks instance Server sebelum merender tampilan apa pun. Nilai yang dikembalikan dari fungsi tersebut menjadi variabel lokal yang terkait dengan fungsi tersebut.

app.dynamicHelpers(( session: function(req, res) ( return req.session; ) ));

Sekarang semua tampilan kita akan memiliki akses ke sesi - data sesi akan tersedia dalam bentuk nama sesi, dll.:

<%= session.name %>

app.lookup

Mengembalikan penangan rute yang terkait dengan jalur yang diberikan.

Katakanlah ada rute berikut:

Anda dapat menggunakan fungsi pencarian untuk memeriksa rute mana yang ditentukan. Ini mungkin berguna untuk kerangka kerja tingkat tinggi yang dibangun di Express.

app.lookup.get("/pengguna/:id"); // => app.lookup.get("/pengguna/:id/:op?"); // => app.lookup.put("/pengguna/:id"); // => app.lookup.all("/pengguna/:id"); // => app.lookup.all("/hei"); // =>

Alias ​​​​untuk app.lookup.HTTP_METHOD() hanyalah app.HTTP_METHOD() - tanpa argumen panggilan balik. Ini adalah pengurangannya. Misalnya yang berikut ini setara:

app.lookup.get("/pengguna"); app.get("/pengguna");

Setiap fungsi yang dikembalikan dilengkapi dengan properti yang berguna:

var fn = app.get("/pengguna/:id/:op?"); fn.regexp // => /^\/pengguna\/(?:([^\/]+?))(?:\/([^\/]+?))?\/?$/i fn .keys // => ["id", "op"] fn.path // => "/user/:id/:op?" fn.metode // => "DAPATKAN"

app.match

Mengembalikan array fungsi panggilan balik yang diaktifkan pada URL tertentu, yang mungkin berisi string kueri, dll. Hal ini berguna untuk memahami rute mana yang memiliki kemampuan merespons.

Katakanlah kita memiliki rute berikut:

app.get("/pengguna/:id", function() ()); app.put("/pengguna/:id", function() ()); app.get("/pengguna/:id/:op?", function() ());

Memanggil match pada GET akan mengembalikan dua fungsi karena :op pada rute terakhir adalah parameter opsional.

app.match.get("/pengguna/1"); // =>

Dan panggilan berikutnya hanya akan mengembalikan satu panggilan balik untuk /user/:id/:op? .

app.match.get("/pengguna/23/edit"); // =>

Kita juga bisa menggunakan all() jika metode HTTP tidak penting bagi kita

app.match.all("/pengguna/20"); // =>

Setiap fungsi dilengkapi dengan properti berikut:

var fn = app.match.get("/pengguna/23/edit"); fn.keys // => ["id", "op"] fn.params // => ( id: "23", op: "edit" ) fn.method // => "GET"

aplikasi.mount (fn)

Tetapkan panggilan balik ke fn yang dipanggil ketika Server ini diteruskan ke Server.use() .

var aplikasi = express.createServer(), blog = express.createServer(); blog.mounted(fungsi(induk) ( //induk adalah aplikasi // ini blog )); app.use(blog);

app.register(ext, ekspor)

Mengaitkan properti ekspor tertentu (ekspor) dari mesin templat dengan ekstensi ext dari file templat.

app.register(".html", require("jade"));

Ini juga berguna dalam kasus perpustakaan yang namanya tidak sama persis dengan ekstensi file templat. Contoh hidup - Haml.js, yang diinstal npm-om sebagai "hamljs" dan kita dapat mendaftarkannya dengan templat ".haml" daripada ".hamljs" seperti yang akan menjadi default:

app.register(".haml", require("haml-js"));

Selain itu, app.register sangat membantu dalam kasus mesin template yang API-nya tidak sesuai dengan spesifikasi Express. Pada contoh di bawah ini kami mengaitkan ekstensi .md dengan penyaji penurunan harga-file. Kami hanya akan merender dalam HTML untuk pertama kalinya - untuk kinerja yang lebih baik - dan kami akan mendukung substitusi variabel dalam bentuk "(nama)".

app.register(".md", ( kompilasi: function(str, options) ( var html = md.toHTML(str); return function(locals) ( return html.replace(/\(([^)]+) \)/g, function(_, nama) ( kembalikan penduduk lokal; ) ));

aplikasi.dengarkan()

Kami mengikat soket server aplikasi ke host: alamat port. Port defaultnya adalah 3000, hostnya adalah INADDR_ANY.

aplikasi.dengarkan(); aplikasi.mendengarkan(3000); app.listen(3000, "n.n.n.n");

Argumen port juga bisa berupa string yang mewakili jalur menuju soket domain unix:

app.listen("/tmp/express.sock");

Sekarang mari kita coba:

$ telnet /tmp/express.sock GET / HTTP/1.1 HTTP/1.1 200 OK Tipe Konten: teks/polos Panjang Konten: 11 Halo Dunia

Peserta proyek

Kontributor utama proyek ini adalah sebagai berikut:

  • TJ Holowaychuk (visionmedia)
  • Ciaran Jessup (ciaranj)
  • Aaron Heckmann (aheckmann)
  • Guillermo Rauch (guille)

Modul pihak ketiga

Modul berikut berfungsi atau dibangun di atas Express:

  • menyediakan perutean sumber daya
  • pesan ekspres menampilkan pemberitahuan popup
  • dukungan konfigurasi ekspres untuk konfigurasi asinkron (memuat data dari Redis, dll.)
  • express-namespace - ruang nama di rute
  • express-expose cukup menerbitkan kode JS ke sisi klien aplikasi
  • ekspresi-params - ekstensi app.param()
  • express-mongoose - plugin untuk merender hasil kueri Mongoose dengan mudah (ORM untuk MongoDB)

Melihat pola sintaksisnya, jika kita ingin menambahkan rute baru ke aplikasi, kita cukup melakukan hal seperti berikut:

Router.get("/app", function(req, res) ( res.render("app", ( title: "Express" )); ));

Apakah ini rutenya? Apakah ini pengontrol?

Hal yang paling menarik adalah rute merupakan fungsi yang mengandung logika. Di dalam rute terdapat fungsi res.render:

Res.render("foo", ( title: "Ekspres" ));

Dalam templat tampilan kita melihat ini:

H1= judul p Selamat datang di #(judul)

Ini adalah dua contoh bagaimana kita dapat menarik data dari pengontrol/rute dan menampilkannya dalam tampilan. Dalam contoh ini kami menampilkan HTML:

Cepat

Selamat datang di Ekspres

Ini semua tampaknya berasal dari masalah - dapatkah suatu rute juga berisi informasi pengontrol? Memang benar demikian, itulah sebabnya ada gerakan di komunitas untuk mengubah nama folder dari rute menjadi pengontrol.

Contoh bagusnya dapat dilihat pada contoh Express MVC.

Namun demi konsistensi, kami akan tetap berpegang pada konvensi terkini dalam panduan ini.

404 kesalahan

Kesalahan sudah mengirim Anda ke Express. File app.js memiliki yang berikut:

/// tangkap 404 dan alihkan ke pengendali kesalahan app.use(function(req, res, next) ( var err = new Error("Tidak ditemukan"); err.status = 404; next(err); ));

Ada error.jade di folder views/.

Memperluas konten blok tata letak h1= pesan h2= error.status pra #(error.stack)

Itu mudah. Jika Anda ingin menyesuaikan halaman 404 Anda, edit saja tampilan ini.

Dasar-dasar Node JS & Express (III).

Mari kita pahami apa itu npm dan untuk apa. Instal mesin template Express dan EJS. Kami melakukan semua pekerjaan persiapan dan mulai membuat situs web kami sendiri di NodeJS.

Kini dengan parameter yang akan terus berubah.

Jika kita perlu membuat referensi ke nilai tertentu, setelah /mews/value . Itu akan berubah. Misalnya: 23, sebagian atau nilai lainnya.

App.get("/news/:id", function(req, res)( res.send("ID adalah - " + req.params.id); ));

Tergantung pada parameter ini, kita dapat mengambil data dari database (database) dan menampilkan artikel tertentu.

Kami memerlukan file html tertentu di mana kami akan mentransfer data id kami dan, bergantung pada data ini, menampilkan informasi ini atau itu.

Kami membutuhkan beberapa mesin templat.

Berkat Express, kita dapat menggunakan beberapa mesin template.

Karena EJS adalah paket opsional, kita perlu menginstalnya.

tekan enter

Setelah itu akan diinstal di proyek kami.

Ini memungkinkan Anda meneruskan data ke berbagai templat, dan templat ini akan memiliki ekstensi .ejs.

Dalam template ini kita akan dapat menampilkan kode html kita beserta kode js yang dimasukkan ke dalamnya (variabel, loop keluaran, dan banyak lagi).

Akan ada templat halaman yang akan berubah tergantung pada data yang ditransfer ke sana.

Hal pertama yang perlu kita lakukan adalah menentukan view engine mana yang akan kita gunakan.

Mesin tampilan pada dasarnya adalah mesin templat.

Karena jumlahnya sangat banyak, dan kami memilih EJS, kami harus menunjukkannya di file index.js kami.

Segera setelah menginisialisasi variabel aplikasi.

App.set("mesin tampilan", "ejs");

Semua file yang akan kita tampilkan akan dicari di folder views secara default.

Pada level yang sama dengan index.js kita akan membuat folder views.

Di dalamnya kita akan membuat file baru news.ejs. Ini akan menjadi semacam template yang akan kita isi.

Kita dapat memasukkan kode html paling umum ke dalam template ini.

Berita

Halaman berita.

Untuk melakukan ini, saya tidak perlu menggunakan metode .send atau .sendFile, tetapi saya memerlukan metode render().

Metode render() mengambil file (template) yang diinginkan di folder views dan dapat menampilkannya di browser. Plus, itu dapat meneruskan parameter tertentu ke template ini.

Ekstensi mungkin tidak ditentukan dalam metode render(). Selanjutnya, Anda dapat meneruskan beberapa parameter ke template itu sendiri. Oleh karena itu, kami meneruskan objek tersebut sebagai parameter kedua. Itu dapat berisi sejumlah besar properti dan nilai.

Katakanlah kita memutuskan untuk meneruskan parameter tertentu newsId dengan nilai req.params.id - yaitu, nilainya akan menjadi id yang dipanggil itu sendiri.

App.get("/news/:id", function(req, res)( render("news", (newsId: req.params.id)); ));

Dengan demikian, sebuah nilai akan diteruskan ke template berita, yang akan disebut newsId dengan nilai id .

Kami dapat menerima dan menampilkan semua ini di file news.ejs.

Mari kita ubah sedikit file news.ejs kita. Kami akan menampilkan ID di judul halaman.

Semuanya dapat ditemukan di dokumentasi mesin template EJS (tautan di atas).

Halaman berita dengan ID =<%= newsId %>

File /views/news.ejs

Berita

Halaman berita dengan ID =<%= newsId %>

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eaque numquam libero, veniam ipsum similique odit molstiae esse quia blanditiis magni debitis aliquam, pariatur nam quaerat quas nemo, facilis temporibus laboriosam. Maiores enim vitae dolore nemo quas aliquam quiacorrupti rerum ipsam ad nesciunt, Architecto, pariatur officiis. Maxime iste ullam quibusdam, nobis voluptas!

file indeks.js

Biarkan ekspres = memerlukan("ekspres"); biarkan aplikasi = ekspres(); app.set("lihat mesin", "ejs"); app.get("/", function(req, res)( res.sendFile(__dirname + "/index.html"); )); app.get("/about", function(req, res)( res.sendFile(__dirname + "/about.html"); )); app.get("/news/:id", function(req, res)( res.render("news", (newsId: req.params.id)); )); aplikasi.mendengarkan(8080);

Kita dapat melewati beberapa parameter. Misalnya:

App.get("/news/:id", function(req, res)( res.render("news", (newsId: req.params.id, newParam: 535 )); ));

Dan pada file news.ejs akan kita tampilkan pada halaman tersebut, contohnya seperti ini:

<%= newParam %>

Selain itu, kita bisa memindahkan objek kita sendiri. Misalnya, mari kita buat sebuah objek:

App.get("/news/:id", function(req, res)( let obj = (judul:"Berita", id:4); res.render("berita", (newsId: req.params.id, newParam: 535)); ));

Dan kita juga bisa mentransfer objek ini. Pertama kita tentukan nama apa yang akan kita transmisikan, lalu kita tunjukkan apa yang kita transmisikan.

Misalnya:

App.get("/news/:id", function(req, res)( let obj = ( title:"News", id: 4); res.render("news", (newsId: req.params.id , Param baru: 535, obj: obj ));

Judul =<%= obj.title %>

tanda pengenal=<%= obj.id %>

<%= newParam %>

Melewati array ke template.

Mari kita membuat array data dan menampilkannya menggunakan loop.

App.get("/news/:id", function(req, res)( let obj = ( title:"News", id: 4, paragraf:["Paragraf", "Teks biasa", "Nomor: 3, 7, 24", 476]); res.render("news", (newsId: req.params.id, newParam: 535, obj: obj)); ));

Sekarang di template itu sendiri kita hanya akan menampilkan array ini dalam satu lingkaran:

    <% obj.paragraphs.forEach(function(item) { %>
  • <%= item %>
  • <% }); %>

File statis dan middleware.

File yang dapat dimasukkan ke dalam file lain.

Sekarang kami memiliki satu template - news.ejs, tapi bayangkan. bahwa jumlahnya banyak. Puluhan. Dan Anda perlu melakukan perubahan pada beberapa bagian kode yang muncul di semua file ini. Banyak perubahan yang harus dilakukan.

Untuk menghindari hal ini, Anda dapat menggunakan file yang dapat dimasukkan ke dalam file lain. Misalnya. Ada file dengan header situs. Dan jika Anda perlu mengubah sesuatu, cukup membuat perubahan hanya pada satu file, karena file tersebut hanya terhubung ke file lain.

Di folder templat tampilan, buat folder bernama blok, dan di dalamnya file hrader.ejs.

File hrader.ejs

  • Ke utama
  • Tentang kami
  • Berita

Sekarang kita perlu menyertakan file ini di semua template. Buka file berita dan segera setelah tag body pembuka tulis:

<% include blocks/header.ejs %>

Jalurnya ditentukan dari folder views, karena mesin template selalu mulai mencari di sana.

File statis.

Mari buat folder baru di level index.js bernama public. Ini akan berisi semua file statis. Ini adalah file css, gambar, dokumen, dll. Semua file itu. yang akan dipanggil dari berbagai halaman situs kami.

Di folder ini kita akan membuat folder lain - css dan di dalamnya kita akan membuat file style.css.

Kami akan mentransfer semua kode gaya dari file index.ejs ke dalamnya

Dalam file .ejs kami menyertakan gaya:

Jika Anda memeriksanya sekarang, tidak akan terjadi apa-apa. Gaya tidak akan terhubung.

Untuk memasukkan file statis kita perlu menggunakan middleware:

Dalam file index.js di atas, tepat setelah app.set , kita harus menulis:

Aplikasi.use("/public",);

Dan sekarang, jika kita menggunakan tautan yang dimulai dengan /public, NodeJS dan Express sendiri akan memahami apa yang kita gunakan file statis dan semuanya akan terhubung dengan benar.

Yang kedua adalah tempat kita mencarinya express.static("public") yaitu di folder /public.

Ringkasnya, dalam kode app.use("/public", express.static("public")); kami melacak tautan yang kami tulis

Jika seperti ini:

Maka dalam kode ini akan menjadi:

App.use("/assets", express.static("public"));

Dalam hal ini, publik menunjuk ke suatu folder!

Jika dibiarkan seperti itu, tidak akan terjadi perubahan. File tersebut akan disertakan karena kami akan melacak tautan aset.

App.use("/assets ", express.static("public "));

Untuk menghindari kebingungan, mereka biasanya membuat link dan folder dengan nama yang sama. Paling sering ini bersifat publik.

Middleware adalah apa yang kita lakukan sebelum kita mengirimkan data apapun ke halaman (server).

Dalam hal ini, ini adalah middleware kami.

Membuat Formulir HTML dan Mengambil Data

Hal pertama yang akan kita lakukan adalah menambahkan formulir itu sendiri ke situs kita.

Buka file about.ejs dan disini kita akan menambahkan form menggunakan teknologi bootstrap.

Masukkan Formulir ke dalam jendela pencarian dan salin formulir pertama dari atas pada halaman yang ditemukan.

Ayo simpan dan jalankan.

permintaan POSTING.

Karena kita akan melakukan permintaan POST, kita perlu menambahkan beberapa atribut ke formulir.

Metode = "posting" - karena permintaan POST

Dan action="" adalah saat Anda perlu mengarahkan ulang pengguna setelah dia mengklik "Kirim". Dalam kasus kami, ini adalah:

Kita perlu melakukan semua hal lain di file index.js

Pertama-tama, kita perlu mengunduh paket bernama body-parser.

Hal ini memungkinkan kita untuk mengambil permintaan POST yang berasal dari formulir dan memprosesnya. Dengan kata lain, dapatkan semua data dari formulir.

Untuk install tulis di folder project di CS.

npm instal body-parser

Tekan enter.

Paket telah diinstal.

Setelah instalasi, Anda harus mengikuti instruksi sederhana.

Mari buka bagian Contoh di situs web dan temukan bagian khusus rute Ekspres di sana

  1. Kami menghubungkan modul yang kami butuhkan.
  2. Var bodyParser = memerlukan("body-parser")

    Var urlencodedParser = bodyParser.urlencoded(( diperpanjang: false ))

    Artinya, parser yang memungkinkan kita mengambil data dari permintaan POST dan mengerjakannya sesuai kebutuhan.

  3. Selanjutnya, berdasarkan dokumentasi, kita melihat bahwa kita perlu melacak permintaan POST dan meneruskan beberapa middleware (urlencodedParser) ke sana. Kami telah melacak permintaan GET sebelumnya.

Kami akan menampilkan data yang diterima dari formulir ke konsol.

Console.log(req.body);

Anda dapat langsung menambahkan cek. Jika tidak ada data formulir yang dikirimkan, kami hanya akan mengeluarkan kesalahan.

Jika (!req.body) mengembalikan res.sendStatus(400)

Dalam formulir itu sendiri, Anda perlu menentukan atribut nama untuk bidang tersebut. Ini akan menjadi nama properti, dan nilainya akan sesuai dengan apa yang dimasukkan pengguna.

Tentang kami. <% include blocks/header.ejs %>

Judul tingkat kedua.

Ke utama

gelar tingkat ketiga.

Signifikansi masalah-masalah ini begitu jelas sehingga konsultasi dengan berbagai aktivis memungkinkan kita melaksanakan tugas-tugas penting dalam mengembangkan sistem partisipasi massa. Pertimbangan ideologis pada tingkat yang lebih tinggi, serta ruang lingkup dan tempat pelatihan personel, memungkinkan kita menilai pentingnya sistem pelatihan personel yang memenuhi kebutuhan mendesak. Namun tidak boleh dilupakan bahwa konsultasi dengan berbagai aset berkontribusi terhadap persiapan dan penerapan sistem pelatihan personel yang memenuhi kebutuhan mendesak.

Namun tidak boleh dilupakan bahwa konsultasi dengan berbagai aset berkontribusi terhadap persiapan dan penerapan sistem pelatihan personel yang memenuhi kebutuhan mendesak.

Kami tidak akan pernah membagikan email Anda kepada orang lain.

Biarkan ekspres = memerlukan("ekspres"); var bodyParser = memerlukan("body-parser"); biarkan aplikasi = ekspres(); var urlencodedParser = bodyParser.urlencoded(( diperpanjang: false )); app.set("lihat mesin", "ejs"); app.use("/public", express.static("public")); app.get("/", function(req, res)( res.render("index"); )); app.get("/about", function(req, res)( res.render("about"); )); app.post("/about", urlencodedParser, function(req, res)( if (!req.body) return res.sendStatus(400); console.log(req.body); res.render("about") ; app.get("/news", function(req, res) ( res.render("news-common",(newParam1:"Param-1")); )); app.get("/news/:id", function(req, res)( let obj = ( judul:"Berita", id: 4, paragraf:["Paragraf", "Teks biasa", "Nomor: 3, 7, 24", 476]); res.render("news", (newsId: req.params.id, newParam: 535, obj: obj)); )); aplikasi.mendengarkan(8080);

Masukkan data dan klik kirim. Di konsol kita akan melihat output dari data ini (properti - nilai).

Halaman akan dimuat ulang setelah mengirimkan formulir dan di konsol kita akan melihat data yang telah dikirim.

Sekarang kita bisa membuatnya agar setelah pengiriman kita menampilkan data lainnya.

Mari kita ubah sedikit kode pada file index.js

App.post("/about", urlencodedParser, function(req, res)( if (!req.body) return res.sendStatus(400); console.log(req.body); res.render(" tentang-sukses", (data: req.body)); });

Dengan cara ini kita akan menampilkan halaman about-success.ejs dan sekarang kita akan membuatnya di folder views. Sebagai parameter kedua kita akan meneruskan data formulir sebagai objek. - (data: req.body)

Tentang kami. <% include blocks/header.ejs %>

Halo, Ini adalah halaman pertama saya di Node.js

Judul tingkat kedua.

Ke utama

Demikian pula penguatan dan pengembangan struktur berkontribusi pada penyiapan dan pelaksanaan sistem pelatihan personel yang memenuhi kebutuhan mendesak. Demikian pula, permulaan pekerjaan sehari-hari dalam membentuk suatu jabatan mengharuskan kita menganalisis kondisi keuangan dan administrasi yang signifikan.

Terima kasih

Surel: <%= data.email %>
Lulus: <%= data.pass %>
adalahPeriksa: <%= data.check %>

Dengan cara ini Anda dapat melacak data yang berasal dari formulir, memeriksa kepatuhannya dan jika pengguna belum mengisi sesuatu, maka menimbulkan kesalahan, dll.

Selain itu, akan lebih mudah untuk mengirim data ini melalui email atau menyimpannya dalam database.

Jika Anda ingin mengirimkannya melalui surat. lalu ada paket lain di npm - Nodemailer. Paket ini memungkinkan Anda mengirim data langsung ke email. Sangat mudah untuk digunakan. Dan dengan bantuannya Anda dapat menerima melalui surat semua data formulir yang diisi oleh pengguna.

NodeJS memberi kita banyak paket tambahan. Misalnya, kami menggunakan Express untuk mempermudah pelacakan tautan dan penggunaan mesin templat. Body-parseer untuk menerima data yang diterima dari formulir. Nodemailer - untuk mengirim data melalui email.

Cara mendapatkan data dari string URL.

Terkadang Anda perlu mendapatkan jenis data ini dari bilah alamat:

http://localhost:8080/news/12?filter-id&city=london

Mari kita lihat cara mendapatkan data ini menggunakan kode ini dari file index.js sebagai contoh:

App.get("/news/:id", function(req, res)( let obj = ( judul:"Berita", id: 4, paragraf:["Paragraf", "Teks biasa", "Nomor: 3, 7, 24", 476]); res.render("news", (newsId: req.params.id, newParam: 535, obj: obj)); ));

Mari kita keluarkan data ini ke konsol:

App.get("/news/:id", function(req, res)( let obj = ( judul:"Berita", id: 4, paragraf:["Paragraf", "Teks biasa", "Nomor: 3, 7, 24", 476]); console.log(req.query); res.render("news", (newsId: req.params.id, newParam: 535, obj: obj)); ));

Di konsol kita akan lihat

( filter: "id", kota: "london")

Ini terkadang berguna.

Artikel ini ditujukan untuk pengembang pemula dan siapa pun yang tertarik bekerja dengan Node js Express. Untuk menguasai ini, Anda harus mengetahui dasar-dasar JavaScript:

Apa itu Node.js?

Node.js adalah runtime JavaScript asinkron berdasarkan mesin JavaScript V8 Chrome. Ini dirancang untuk membuat aplikasi jaringan yang skalabel.

Node.js memungkinkan Anda menulis kode JavaScript sisi server. Sekarang Anda mungkin bertanya-tanya bagaimana caranya? JavaScript adalah bahasa yang berjalan di browser. Browser menerima kode JavaScript dan mengkompilasinya menjadi perintah. Pencipta Node.js menggunakan mesin Chrome dan membuat runtime ( waktu proses) agar berfungsi di server. Ini adalah media di mana bahasa dapat ditafsirkan. Jadi apa yang kita punya sekarang? Cara untuk menulis JavaScript di backend.

Mengenai definisinya, Anda mungkin bertanya-tanya apa arti istilah "asinkron" dalam konteks ini. JavaScript adalah bahasa berulir tunggal. Oleh karena itu, Anda tidak ingin kejadian mengganggu thread utama eksekusi. Ini berarti memproses peristiwa tanpa mengganggu thread utama.

Node.js didasarkan pada desain non-pemblokiran ini, menjadikannya salah satu alat tercepat untuk membangun aplikasi web. Dalam contoh "Hello World" berikut, banyak koneksi yang dapat diproses secara bersamaan. Setiap koneksi memicu panggilan balik.

Contoh Node js Express ini memiliki enam langkah sederhana.

  1. Instal Node.js untuk platform Anda (MacOS, Windows atau Linux)

Node.js

Node.js® adalah runtime JavaScript yang dibangun ke dalam mesin JavaScript V8 untuk Chrome. Node.js menggunakan I/O yang digerakkan oleh peristiwa dan non-pemblokiran...

Langkah pertama adalah mendapatkan instance JavaScript di mesin lokal Anda. Ketik nodejs.org di bilah alamat browser Anda atau klik tautannya, dan selesai. Jendela peluncuran akan segera memberikan apa yang Anda inginkan. Saat saya meluncurkan Ubuntu di komputer saya, versi Node.js yang sesuai untuk sistem operasi saya ditampilkan. Unduh dan instal. Ini akan memberi Anda alat yang Anda perlukan untuk menjalankan server di komputer lokal Anda:

  1. Buka prompt perintah dan ketik

mkdir aplikasi saya cd aplikasi saya

Perintah Node js Express Post ini bersifat universal untuk sistem operasi apa pun. Yang pertama akan membuat direktori baru di dalam direktori tempat Anda berada saat ini, mkdir = "make direktori" . Yang terakhir akan berubah ke direktori yang baru dibuat ini, cd = "change Directory" .

  1. Jalankan proyek Anda dan tautkan ke npm

Setelah membuat direktori bernama myapp, Anda perlu menjalankan proyek dan menghubungkannya dengan npm.

Npm adalah kependekan dari manajer paket simpul ( Manajer paket simpul). Di sinilah semua paket Node berada. Mereka dapat dianggap sebagai paket kode, modul yang menjalankan fungsi tertentu. Kami menggunakan antarmuka program aplikasi, API, yang disediakan oleh modul ini.

Modul tersebut, pada gilirannya, bertindak sebagai kotak hitam dengan tombol dan tuas yang dapat didorong dan ditarik untuk mencapai hasil yang diinginkan. Menjalankan perintah di bawah ini akan memulai proyek Anda:

Itu membuat file package.json di folder myapp. File tersebut berisi tautan ke semua paket npm yang dimuat ke dalam proyek.

Perintah tersebut akan meminta Anda memasukkan beberapa opsi tindakan. Anda dapat memasuki jalur Anda melalui semuanya kecuali yang ini:

titik masuk: (index.js)

Anda ingin mengubahnya menjadi:

  1. Instal Express di direktori myapp

Express adalah kerangka aplikasi web Node.js yang minimal dan fleksibel yang menyediakan serangkaian fitur tangguh untuk web.

Saat berada di direktori myapp, jalankan:

npm instal ekspres --simpan

Perintah instalasi akan melanjutkan pencarian paket file Node js Express yang akan diinstal. Instal di proyek Anda.

Sekarang folder node_modules dibuat di root proyek Anda. Menambahkan -save memungkinkan paket disimpan ke daftar ketergantungan yang terletak di package.json di direktori myapp.

Express menyediakan seperangkat alat untuk membuat dan menjalankan aplikasi web. Express telah menjadi sangat populer sehingga sekarang menjadi standar di sebagian besar aplikasi Node.js. Saya sangat merekomendasikan menggunakan Express.

  1. Luncurkan editor teks dan buat file bernama app.js

Setelah menginstal Express Node, tambahkan kode berikut ke file yang dibuat:

var express = memerlukan("ekspres"); var aplikasi = ekspres(); app.get("/", function (req, res) ( res.send("Halo Dunia!"); )); app.listen(3000, function() ( console.log("Contoh aplikasi mendengarkan pada port 3000!"); ));

Di sini Anda perlu menggunakan paket yang baru saja diinstal. Baris pertama mendeklarasikan variabel yang akan berisi modul ekspres, yang terletak di folder node_modules.

Modul adalah sebuah fungsi. Menetapkan pemanggilan fungsi ke variabel lain memberikan akses ke seperangkat alat yang telah ditentukan sebelumnya yang membuat pekerjaan di masa depan lebih mudah. Anda dapat menganggap aplikasi sementara sebagai objek yang metodenya Anda gunakan untuk membuat program sebenarnya.

Metode mendengarkan memulai server dan mendengarkan koneksi pada port 3000. Dia menjawab “Halo Dunia! " untuk permintaan GET ke URL root (/). Untuk jalur lainnya, ia akan merespons dengan 404 Not Found.

  1. Luncurkan aplikasi

Masukkan perintah:

Setelah menjalankan perintah, masukkan http://localhost:3000/ di browser Anda untuk melihat hasilnya. Anda juga harus melihat " Contoh aplikasi yang mendengarkan pada port 3000».