Hapi.js adalah kerangka kerja untuk membangun aplikasi web. Posting ini berisi semua hal penting untuk memulai yang baru. Sayangnya, penulisnya sama sekali bukan penulis, jadi akan ada banyak kode dan beberapa kata.
MVP
Taruh banyak dependensi:
npm i @hapi/hapi @hapi/boom filepaths hapi-boom-decorators
- hapi / hapi - sebenarnya, server kami
- hapi / boom - modul untuk menghasilkan jawaban standar
- hapi-boom-dekorator - pembantu untuk hapi / boom
- filepaths - sebuah utilitas yang secara rekursif membaca folder
Buat struktur folder dan banyak file mulai:

Dalam ./src/routes/ kami menambahkan deskripsi titik akhir api, 1 file - 1 titik akhir:
./src/server.js - modul yang mengekspor server itu sendiri.
Di ./server.js yang kita lakukan adalah memanggil createServer ()
#!/usr/bin/env node const createServer = require('./src/server'); createServer();
Kami meluncurkan
node server.js
Dan periksa:
curl http://127.0.0.1:3030/ {"result":"ok","message":"Hello World!"} curl http://127.0.0.1:3030/test {"statusCode":404,"error":"Not Found","message":"Not Found"}
Di alam liar
Dalam proyek nyata, minimal, kita membutuhkan database, logger, otorisasi, penanganan kesalahan, dan banyak lagi.
Tambahkan sekuel
Sequelize ORM terhubung sebagai modul:
... const Sequelize = require('sequelize'); ... await server.register([ ... { plugin: require('hapi-sequelizejs'), options: [ { name: config.db.database,
Basis data menjadi tersedia di dalam rute melalui panggilan:
async function response(request) { const model = request.getModel('_', '_'); }
Suntikkan modul tambahan ke dalam permintaan
Hal ini diperlukan untuk mencegat acara "onRequest", di mana kami akan menyuntikkan konfigurasi dan logger ke objek permintaan:
... const Logger = require('./libs/Logger'); ... async function createServer(logLVL=config.logLVL) { ... const logger = new Logger(logLVL, 'my-hapi-app'); ... server.ext({ type: 'onRequest', method: async function (request, h) { request.server.config = Object.assign({}, config); request.server.logger = logger; return h.continue; } }); ... }
Setelah itu, di dalam penangan permintaan, kita akan memiliki akses ke config, logger, dan basis data, tanpa perlu menambahkan sesuatu ke dalam modul module:
Dengan demikian, penangan permintaan pada input akan menerima semua yang diperlukan untuk pemrosesan, dan tidak perlu menyertakan modul yang sama setiap waktu dari waktu ke waktu.
Login
Otorisasi dalam hapi dibuat dalam bentuk modul.
... const AuthBearer = require('hapi-auth-bearer-token'); ... async function createServer(logLVL=config.logLVL) { ... await server.register([ AuthBearer, ... ]); server.auth.strategy('token', 'bearer-access-token', {
Dan juga di dalam rute Anda perlu menentukan jenis otorisasi yang digunakan:
module.exports = { method: 'GET', path: '/', auth: 'token',
Jika beberapa jenis otorisasi digunakan:
auth: { strategies: ['token1', 'token2', 'something_else'] },
Menangani kesalahan
Secara default, boom menghasilkan kesalahan dengan cara standar, seringkali jawaban ini perlu dibungkus dalam format mereka sendiri.
server.ext('onPreResponse', function (request, h) {
Skema data
Ini adalah topik kecil tapi sangat penting. Skema data memungkinkan Anda untuk memeriksa validitas permintaan dan kebenaran tanggapan. Seberapa baik Anda menggambarkan skema ini, demikian juga kesombongan dan autotest akan berkualitas seperti itu.
Semua skema data dijelaskan melalui joi. Mari kita buat contoh untuk otorisasi pengguna:
const Joi = require('@hapi/joi'); const Boom = require('boom'); async function response(request) {
Pengujian:
curl -X GET "http://localhost:3030/auth?login=pupkin@gmail.com&password=12345"

Sekarang kirim alih-alih surat, hanya login:
curl -X GET "http://localhost:3030/auth?login=pupkin&password=12345"

Jika jawabannya tidak cocok dengan skema respons, maka server juga akan jatuh ke dalam kesalahan 500.
Jika proyek mulai memproses lebih dari 1 permintaan per jam, mungkin perlu membatasi verifikasi tanggapan, seperti verifikasi adalah operasi intensif sumber daya. Ada parameter untuk ini: "sampel"
module.exports = { method: 'GET', path: '/auth', options: { handler: response, validate: { query: requestScheme }, response: { sample: 50, schema: responseScheme } } };
Dengan demikian, hanya 50% permintaan yang akan divalidasi.
Sangat penting untuk menggambarkan nilai dan contoh default, di masa depan mereka akan digunakan untuk menghasilkan dokumentasi dan autotest.
Sombong / OpenAPI
Kami membutuhkan banyak modul tambahan:
npm i hapi-swagger @hapi/inert @hapi/vision
Kami menghubungkan mereka ke server.js
... const Inert = require('@hapi/inert'); const Vision = require('@hapi/vision'); const HapiSwagger = require('hapi-swagger'); const Package = require('../package'); ... const swaggerOptions = { info: { title: Package.name + ' API Documentation', description: Package.description }, jsonPath: '/documentation.json', documentationPath: '/documentation', schemes: ['https', 'http'], host: config.swaggerHost, debug: true }; ... async function createServer(logLVL=config.logLVL) { ... await server.register([ ... Inert, Vision, { plugin: HapiSwagger, options: swaggerOptions }, ... ]); ... });
Dan di setiap rute Anda harus meletakkan tag "api":
module.exports = { method: 'GET', path: '/auth', options: { handler: response, tags: [ 'api' ],
Sekarang di http: // localhost: 3030 / dokumentasi web-face dengan dokumentasi akan tersedia, dan di http: // localhost: 3030 / dokumentasi.json .json sebuah deskripsi.

Pembuatan Tes Otomatis
Jika kami telah secara kualitatif menggambarkan skema permintaan dan respons, menyiapkan basis data seed yang sesuai dengan contoh-contoh yang dijelaskan dalam contoh permintaan, maka, menggunakan skema terkenal, Anda dapat secara otomatis menghasilkan permintaan dan memeriksa kode respons server.
Misalnya, dalam GET: / auth login dan kata sandi parameter diharapkan, kami akan mengambilnya dari contoh yang kami tentukan dalam diagram:
const requestScheme =Joi.object({ login: Joi.string().email().required().example('pupkin@gmail.com'), password: Joi.string().required().example('12345') });
Dan jika server merespons dengan HTTP-200-OK, maka kami akan menganggap bahwa tes telah berlalu.
Sayangnya, tidak ada modul yang cocok yang siap pakai; Anda harus berbicara sedikit:
Jangan lupa tentang dependensi:
npm i request-promise mocha sync-request
Dan tentang package.json
... "scripts": { "test": "mocha", "dbinit": "node ./scripts/dbInit.js" }, ...
Kami memeriksa:
npm test

Dan jika kuncinya adalah semacam skema data, atau jawabannya tidak cocok dengan skema tersebut:

Dan jangan lupa bahwa cepat atau lambat tes akan menjadi peka terhadap data dalam database. Sebelum menjalankan tes, Anda harus setidaknya menghapus database.
Seluruh Sumber