Làm thế nào để Express và hapi so sánh với nhau?


133

Từ quan điểm thiết kế và phát triển ứng dụng web, Express và Hapi so sánh với nhau như thế nào? Đối với các ví dụ cơ bản, chúng có vẻ giống nhau, tuy nhiên tôi muốn tìm hiểu thêm về các khác biệt chính trong cấu trúc ứng dụng tổng thể.

Ví dụ, theo như tôi đã biết, Hapi sử dụng một cơ chế định tuyến khác không tính đến thứ tự đăng ký, có thể thực hiện tra cứu nhanh hơn, nhưng bị giới hạn so với Express. Có sự khác biệt quan trọng khác?

Ngoài ra còn có một bài viết về việc chọn Hapi (trên Express) để phát triển trang web npmjs.com mới, bài viết này nói rằng "Hệ thống plugin của Hapi có nghĩa là chúng ta có thể cô lập các khía cạnh và dịch vụ khác nhau của ứng dụng theo cách cho phép microservice trong Tương lai, Express, mặt khác, đòi hỏi một chút cấu hình để có được chức năng tương tự ", chính xác thì nó có nghĩa là gì?

Câu trả lời:


231

Đây là một câu hỏi lớn và cần một câu trả lời dài để hoàn thành, vì vậy tôi sẽ chỉ giải quyết một tập hợp con của những khác biệt quan trọng nhất. Xin lỗi rằng đó vẫn là một câu trả lời dài dòng.

Chúng giống nhau như thế nào?

Bạn hoàn toàn đúng khi bạn nói:

Đối với các ví dụ cơ bản, chúng có vẻ giống nhau

Cả hai khung đều giải quyết cùng một vấn đề cơ bản: Cung cấp API thuận tiện để xây dựng các máy chủ HTTP trong nút. Điều đó có nghĩa là, thuận tiện hơn so với chỉ sử dụng httpmô đun gốc cấp thấp hơn . Các httpmô-đun có thể làm tất cả mọi thứ chúng tôi muốn nhưng nó tẻ nhạt với các ứng dụng ghi với.

Để đạt được điều này, cả hai đều sử dụng các khái niệm đã có trong các khung web cao cấp trong một thời gian dài: định tuyến, xử lý, bổ trợ, mô-đun xác thực. Họ có thể không phải lúc nào cũng có cùng tên nhưng chúng gần tương đương nhau.

Hầu hết các ví dụ cơ bản trông giống như thế này:

  • Tạo một tuyến đường
  • Chạy một chức năng khi tuyến đường được yêu cầu, chuẩn bị phản hồi
  • Đáp ứng yêu cầu

Bày tỏ:

app.get('/', function (req, res) {

    getSomeValue(function (obj) {

        res.json({an: 'object'});
    });
});

hapi:

server.route({
    method: 'GET',
    path: '/',
    handler: function (request, reply) {

        getSomeValue(function (obj) {

            reply(obj);
        });
    }
});

Sự khác biệt không chính xác là đột phá ở đây phải không? Vậy tại sao chọn cái này hơn cái kia?

Họ khác nhau như thế nào?

Câu trả lời đơn giản là hapi còn nhiều hơn thế và nó còn vượt trội hơn rất nhiều. Điều đó có thể không rõ ràng khi bạn chỉ nhìn vào ví dụ đơn giản từ phía trên. Trong thực tế, đây là cố ý. Các trường hợp đơn giản được giữ đơn giản. Vì vậy, hãy xem xét một số khác biệt lớn:

Triết học

Express được dự định là rất tối thiểu. Bằng cách cung cấp cho bạn một API nhỏ chỉ với một lớp bụi mỏng trên đầu http, bạn vẫn tự mình làm rất nhiều về việc thêm chức năng bổ sung. Nếu bạn muốn đọc phần thân của một yêu cầu đến (một nhiệm vụ khá phổ biến), bạn cần cài đặt một mô-đun riêng . Nếu bạn đang mong đợi các loại nội dung khác nhau được gửi đến tuyến đường đó, bạn cũng cần kiểm traContent-type tiêu đề để kiểm tra xem đó là gì và phân tích nó phù hợp (ví dụ: dữ liệu biểu mẫu so với JSON so với đa phần), thường sử dụng các mô-đun riêng biệt .

hapi có một bộ tính năng phong phú, thường được hiển thị thông qua các tùy chọn cấu hình, thay vì yêu cầu viết mã. Ví dụ: nếu chúng tôi muốn đảm bảo phần thân yêu cầu (tải trọng) được đọc đầy đủ vào bộ nhớ và được phân tích cú pháp thích hợp (tự động dựa trên loại nội dung) trước khi trình xử lý được chạy, đó chỉ là một tùy chọn đơn giản :

server.route({
    config: {
        payload: {
            output: 'data',
            parse: true
        }
    },
    method: 'GET',
    path: '/',
    handler: function (request, reply) {

        reply(request.payload);
    }
});

Đặc trưng

Bạn chỉ cần so sánh tài liệu API trên cả hai dự án để thấy rằng hapi cung cấp một bộ tính năng lớn hơn.

hapi bao gồm một số tính năng được tích hợp sẵn mà Express không có (theo như tôi biết):

Khả năng mở rộng & mô đun

hapi và Express đi về khả năng mở rộng theo một cách hoàn toàn khác. Với Express, bạn có các chức năng trung gian . Các hàm Middleware là loại bộ lọc giống như bạn xếp chồng lên nhau và tất cả các yêu cầu chạy qua chúng trước khi nhấn vào trình xử lý của bạn.

hapi có vòng đời yêu cầu và cung cấp các điểm mở rộng , có thể so sánh với các hàm phần mềm trung gian nhưng tồn tại một số điểm được xác định trong vòng đời yêu cầu.

Một trong những lý do khiến Walmart xây dựng hapi và ngừng sử dụng Express là sự thất vọng với việc khó chia ứng dụng Express thành các phần riêng biệt và khiến các thành viên khác trong nhóm làm việc an toàn trên phần của họ. Vì lý do này, họ đã tạo ra hệ thống plugin trong hapi.

Một plugin giống như một ứng dụng phụ, bạn có thể làm mọi thứ có thể trong ứng dụng hapi, thêm tuyến đường, điểm mở rộng, v.v ... Trong một plugin bạn có thể chắc chắn rằng bạn không phá vỡ một phần khác của ứng dụng, bởi vì thứ tự của đăng ký cho các tuyến không quan trọng và bạn không thể tạo các tuyến xung đột. Sau đó, bạn có thể kết hợp các plugin này vào một máy chủ và triển khai nó.

Hệ sinh thái

Bởi vì Express cung cấp cho bạn rất ít ra khỏi hộp, bạn cần phải nhìn ra bên ngoài khi bạn cần thêm bất cứ điều gì vào dự án của bạn. Rất nhiều lần khi làm việc với hapi, tính năng mà bạn cần là tích hợp sẵn hoặc có một mô-đun được tạo bởi nhóm nòng cốt.

Âm thanh tối thiểu tuyệt vời. Nhưng nếu bạn đang xây dựng một ứng dụng sản xuất nghiêm túc, rất có thể cuối cùng bạn sẽ cần tất cả những thứ này.

Bảo vệ

hapi được nhóm của Walmart thiết kế để điều hành giao thông Thứ Sáu Đen, vì vậy an ninh và ổn định luôn là mối quan tâm hàng đầu. Vì lý do này, khung làm thêm rất nhiều thứ như hạn chế kích thước tải trọng đến để tránh làm cạn kiệt bộ nhớ quy trình của bạn. Nó cũng có các tùy chọn cho những thứ như độ trễ vòng lặp sự kiện tối đa, bộ nhớ RSS tối đa được sử dụng và kích thước tối đa của heap v8, ngoài ra máy chủ của bạn sẽ phản hồi với thời gian chờ 503 thay vì chỉ bị sập.

Tóm lược

Đánh giá cả hai chính họ. Hãy suy nghĩ về nhu cầu của bạn và điều nào trong hai điều này giải quyết mối quan tâm lớn nhất của bạn. Hãy ngâm mình trong hai cộng đồng (IRC, Gitter, Github), xem bạn thích cái nào hơn. Đừng hiểu lời tôi. Và hạnh phúc hack!


TUYÊN BỐ TỪ CHỐI: Tôi thiên vị là tác giả của một cuốn sách về hapi và ở trên phần lớn là ý kiến ​​cá nhân của tôi.


7
Matt, cảm ơn bạn vì bài viết rộng rãi, phần "mở rộng & mô đun" và "bảo mật" là những phần hữu ích nhất đối với tôi. Tôi đoán điều đáng nói là hệ thống định tuyến mới trong Express 4 cung cấp tính mô đun được cải thiện cho các ứng dụng phụ.
Ali Shakiba

1
Matt trả lời tuyệt vời. Chúng tôi cũng bối rối b / w Hapi và Express, một nhược điểm chúng tôi gặp với Hapi là nó không có sự hỗ trợ cộng đồng rộng rãi như Express và có thể là một vấn đề lớn nếu chúng tôi bị mắc kẹt ở đâu đó. Cần ý kiến ​​của bạn về cùng.
Aman Gupta

1
Express là chung chung, trong khi hapi là một doanh nghiệp nhiều hơn một chút.
Windmaomao

1
@MattHarrison câu trả lời tuyệt vời, ngay bây giờ tôi đang đọc cuốn sách của bạn trên Hapi, nó thật tuyệt. Tôi sắp phát triển một thị trường mới cho sách sử dụng Hapi trên backend và vue.js trên frontend, sau khi làm quen với Hapi, tôi muốn tham gia tích cực vào dự án Hapi.
Humoyun Ahmad

1
@Humoyun Tuyệt vời! Tuy nhiên, hãy lưu ý rằng có một phiên bản chính mới của hapi với một số thay đổi đáng kể kể từ <= v16.0.0. Tôi hiện đang sản xuất một loạt screencast được thiết kế để mọi người tìm hiểu v17: youtube.com/playlist?list=PLi303AVTbxaxqjaSWPg94nccY IfqNoCHz
Matt Harrison

54

Tổ chức của tôi đang đi với Hapi. Đây là lý do tại sao chúng tôi thích nó.

Hapi là:

  • Được hỗ trợ bởi quân đoàn lớn. Điều này có nghĩa là sự hỗ trợ của cộng đồng sẽ mạnh mẽ và dành cho bạn trong suốt các phiên bản tương lai. Thật dễ dàng để tìm thấy những người Hapi đam mê, và có những hướng dẫn tốt ngoài đó (mặc dù không nhiều và ngổn ngang như các hướng dẫn của ExpressJs). Kể từ ngày đăng bài này npm và Walmart sử dụng Hapi.
  • Nó có thể tạo điều kiện thuận lợi cho công việc của các nhóm phân phối làm việc trên các phần khác nhau của dịch vụ phụ trợ mà không cần phải có kiến ​​thức toàn diện về phần còn lại của bề mặt API (kiến trúc plugin của Hapi là mẫu mực của chất lượng này).
  • Hãy để khung làm việc mà khung được cho là: cấu hình mọi thứ. Sau đó, khung nên vô hình và cho phép các nhà phát triển tập trung năng lượng sáng tạo thực sự của họ vào việc xây dựng logic kinh doanh. Sau khi sử dụng Hapi được một năm, tôi chắc chắn cảm thấy Hapi hoàn thành việc này. Tôi cảm thấy hạnh phúc!

Nếu bạn muốn nghe trực tiếp từ Eran Hammer (lãnh đạo của Hapi)

Trong bốn năm qua, hapi đã trở thành khuôn khổ lựa chọn cho nhiều dự án, dù lớn hay nhỏ. Điều làm cho hapi trở nên độc đáo là khả năng mở rộng quy mô cho các triển khai lớn và các nhóm lớn. Khi một dự án phát triển, sự phức tạp của nó - độ phức tạp kỹ thuật và độ phức tạp của quy trình. Kiến trúc và triết lý của hapi's xử lý sự phức tạp gia tăng mà không cần phải liên tục cấu trúc lại mã [đọc thêm]

Bắt đầu với Hapi sẽ không dễ như ExpressJs vì Hapi không có cùng "sức mạnh ngôi sao" ... nhưng một khi bạn cảm thấy thoải mái, bạn sẽ nhận được RẤT NHIỀU dặm. Mất khoảng 2 tháng là một hacker mới vô trách nhiệm sử dụng ExpressJs trong một vài năm. Nếu bạn là nhà phát triển phụ trợ dày dạn, bạn sẽ biết cách đọc tài liệu và thậm chí bạn có thể sẽ không nhận thấy điều này.

Các lĩnh vực tài liệu Hapi có thể cải thiện về:

  1. Cách xác thực người dùng và tạo phiên
  2. xử lý Yêu cầu chéo nguồn gốc (CORS)
  3. tải lên các tập tin (nhiều phần, chunked)

Tôi nghĩ rằng xác thực sẽ là phần thử thách nhất vì bạn phải quyết định nên sử dụng chiến lược xác thực nào (Xác thực cơ bản, Cookies, Mã thông báo JWT, OAuth). Mặc dù về mặt kỹ thuật không phải là vấn đề của Hapi rằng các phiên / cảnh xác thực bị phân mảnh ... nhưng tôi ước rằng họ cung cấp một số thao tác cầm tay cho việc này. Nó sẽ làm tăng đáng kể hạnh phúc của nhà phát triển.

Hai phần còn lại thực sự không khó lắm, các tài liệu chỉ có thể được viết tốt hơn một chút.


3

Thông tin nhanh về Hapi Hoặc Tại sao Hapi JS?

Hapi là trung tâm cấu hình Nó có xác thực và ủy quyền được xây dựng trong khung Nó được phát hành trong bầu không khí thử nghiệm trận chiến và đã thực sự chứng minh giá trị của nó Tất cả các mô-đun có phạm vi kiểm tra 100% Nó đăng ký mức độ trừu tượng cao nhất từ ​​lõi HTTP Dễ dàng có thể nhận thấy thông qua kiến ​​trúc plugin

Hapi là một lựa chọn hiệu suất tốt hơn khôn ngoan Hapi sử dụng một cơ chế định tuyến khác, có thể thực hiện tra cứu nhanh hơn và tính đến thứ tự đăng ký. Tuy nhiên, nó khá hạn chế khi so sánh với Express. Và nhờ hệ thống plugin Hapi, có thể cô lập các khía cạnh và dịch vụ khác nhau sẽ giúp ứng dụng theo nhiều cách trong tương lai.

Sử dụng

Hapi là khung được ưa thích nhất khi so sánh với Express. Hapi được sử dụng chủ yếu cho các ứng dụng doanh nghiệp quy mô lớn.

Một số lý do khiến các nhà phát triển không chọn Express khi tạo ứng dụng doanh nghiệp là:

Các tuyến đường khó soạn thảo trong Express

Middleware có được trong hầu hết thời gian; mỗi lần bạn xác định các tuyến đường, bạn phải viết bao nhiêu số mã.

Hapi sẽ là lựa chọn tốt nhất cho nhà phát triển muốn xây dựng API RESTful. Hapi có kiến ​​trúc vi dịch vụ và cũng có thể chuyển điều khiển từ trình xử lý này sang trình xử lý khác dựa trên các tham số nhất định. Với plugin Hapi, bạn có thể tận hưởng mức độ trừu tượng cao hơn xung quanh HTTP vì bạn có thể phân chia logic nghiệp vụ thành các phần dễ quản lý.

Một lợi thế lớn khác với Hapi là nó cung cấp các thông báo lỗi chi tiết khi bạn hiểu sai. Hapi cũng cho phép bạn định cấu hình kích thước tải lên tệp của bạn theo mặc định. Nếu kích thước tải lên tối đa bị giới hạn, bạn có thể gửi thông báo lỗi cho người dùng truyền tải rằng kích thước tệp quá lớn. Điều này sẽ bảo vệ máy chủ của bạn khỏi sự cố vì các tệp tải lên sẽ không còn cố gắng đệm toàn bộ tệp.

  1. Bất cứ điều gì bạn có thể đạt được bằng cách sử dụng express cũng có thể dễ dàng đạt được bằng cách sử dụng hapi.js.

  2. Hapi.js rất phong cách và tổ chức mã rất tốt. Nếu bạn thấy cách nó định tuyến và đưa logic cốt lõi vào các bộ điều khiển, bạn chắc chắn sẽ thích nó.

  3. Hapi.js chính thức cung cấp một số plugin dành riêng cho phạm vi hapi.js từ auth dựa trên mã thông báo đến quản lý phiên và nhiều plugin khác, đó là một quảng cáo trên. Điều đó không có nghĩa là không thể sử dụng npm truyền thống, tất cả chúng đều được hỗ trợ bởi hapi.js

  4. Nếu bạn viết mã trong hapi.js, một mã sẽ rất dễ bảo trì.


"Nếu bạn thấy cách nó định tuyến và đặt logic lõi trong bộ điều khiển ...". Tôi không thấy bất kỳ ví dụ nào trong tài liệu cho thấy việc sử dụng bộ điều khiển. Tất cả các ví dụ định tuyến sử dụng thuộc tính handler là một hàm. Tôi so sánh theo cách này với những gì mà Laravel (khung công tác PHP) và AdonisJs (khung Node.js) làm để định tuyến trong đó chúng ta có thể sử dụng các bộ điều khiển để định tuyến. Tôi có thể đã bỏ lỡ các phần của tài liệu HAPI hiển thị việc sử dụng bộ điều khiển để định tuyến. Vì vậy, nếu tính năng này tồn tại, nó sẽ tốt cho tôi, vì tôi đã quen với việc sử dụng các bộ điều khiển để định tuyến trong Laravel.
Lex Soft

1

Gần đây tôi đã bắt đầu sử dụng Hapi và tôi khá hài lòng với nó. Lý do của tôi là

  1. Dễ kiểm tra hơn. Ví dụ:

    • server.inject cho phép bạn chạy ứng dụng và nhận phản hồi mà không cần chạy và nghe.
    • server.info cung cấp cho uri hiện tại, cổng, vv
    • server.settings truy cập cấu hình, vd server.settings.cache được cung cấp bộ đệm hiện tại
    • khi nghi ngờ nhìn vào /test thư mục cho bất kỳ phần nào của ứng dụng hoặc các plugin được hỗ trợ để xem các đề xuất về cách giả / kiểm tra / sơ khai, v.v.
    • ý nghĩa của tôi là mô hình kiến ​​trúc của hapi cho phép bạn tin tưởng nhưng xác minh, ví dụ như các plugin của tôi đã được đăng ký chưa? Làm thế nào tôi có thể khai báo một phụ thuộc mô-đun ?
  2. Nó hoạt động ngoài hộp, ví dụ như tải lên tệp , trả về luồng từ điểm cuối, v.v.

  3. Các plugin thiết yếu được duy trì cùng với thư viện lõi. ví dụ phân tích cú pháp mẫu , bộ nhớ đệm , vv Lợi ích bổ sung là các tiêu chuẩn mã hóa tương tự được áp dụng trên các điều thiết yếu.

  4. Sane lỗi và xử lý lỗi. Hapi xác nhận các tùy chọn cấu hình và giữ một bảng tuyến nội bộ để ngăn các tuyến trùng lặp. Điều này khá hữu ích trong khi học vì các lỗi được ném sớm thay vì các hành vi không mong muốn cần gỡ lỗi.


-1

Chỉ cần thêm một điểm nữa, Hapi đã bắt đầu hỗ trợ các cuộc gọi 'http2' từ phiên bản 16 trở đi (nếu tôi không sai). Tuy nhiên, express vẫn chưa hỗ trợ mô-đun 'http2' trực tiếp cho đến express 4. Mặc dù họ đã phát hành tính năng này trong phiên bản alpha của express 5.


-2
'use strict';
const Hapi = require('hapi');
const Basic = require('hapi-auth-basic');
const server = new Hapi.Server();
server.connection({
    port: 2090,
    host: 'localhost'
});


var vorpal = require('vorpal')();
const chalk = vorpal.chalk;
var fs = require("fs");

var utenti = [{
        name: 'a',
        pass: 'b'
    },
    {
        name: 'c',
        pass: 'd'
    }
];

const users = {
    john: {
        username: 'john',
        password: 'secret',
        name: 'John Doe',
        id: '2133d32a'
    },
    paul: {
        username: 'paul',
        password: 'password',
        name: 'Paul Newman',
        id: '2133d32b'
    }
};

var messaggi = [{
        destinazione: 'a',
        sorgente: 'c',
        messsaggio: 'ciao'
    },
    {
        destinazione: 'a',
        sorgente: 'c',
        messsaggio: 'addio'
    },
    {
        destinazione: 'c',
        sorgente: 'a',
        messsaggio: 'arrivederci'
    }
];

var login = '';
var loggato = false;

vorpal
    .command('login <name> <pass>')
    .description('Effettua il login al sistema')
    .action(function (args, callback) {
        loggato = false;
        utenti.forEach(element => {
            if ((element.name == args.name) && (element.pass == args.pass)) {
                loggato = true;
                login = args.name;
                console.log("Accesso effettuato");
            }
        });
        if (!loggato)
            console.log("Login e Password errati");
        callback();
    });

vorpal
    .command('leggi')
    .description('Leggi i messaggi ricevuti')
    .action(function (args, callback) {
        if (loggato) {
            var estratti = messaggi.filter(function (element) {
                return element.destinazione == login;
            });

            estratti.forEach(element => {
                console.log("mittente : " + element.sorgente);
                console.log(chalk.red(element.messsaggio));
            });
        } else {
            console.log("Devi prima loggarti");
        }
        callback();
    });

vorpal
    .command('invia <dest> "<messaggio>"')
    .description('Invia un messaggio ad un altro utente')
    .action(function (args, callback) {
        if (loggato) {
            var trovato = utenti.find(function (element) {
                return element.name == args.dest;
            });
            if (trovato != undefined) {
                messaggi.push({
                    destinazione: args.dest,
                    sorgente: login,
                    messsaggio: args.messaggio
                });
                console.log(messaggi);
            }
        } else {
            console.log("Devi prima loggarti");
        }
        callback();
    });

vorpal
    .command('crea <login> <pass>')
    .description('Crea un nuovo utente')
    .action(function (args, callback) {
        var trovato = utenti.find(function (element) {
            return element.name == args.login;
        });
        if (trovato == undefined) {
            utenti.push({
                name: args.login,
                pass: args.pass
            });
            console.log(utenti);
        }
        callback();
    });

vorpal
    .command('file leggi utenti')
    .description('Legge il file utenti')
    .action(function (args, callback) {
        var contents = fs.readFileSync("utenti.json");
        utenti = JSON.parse(contents);
        callback();
    });

vorpal
    .command('file scrivi utenti')
    .description('Scrive il file utenti')
    .action(function (args, callback) {
        var jsontostring = JSON.stringify(utenti);
        fs.writeFile('utenti.json', jsontostring, function (err) {
            if (err) {
                return console.error(err);
            }
        });
        callback();
    });

vorpal
    .command('file leggi messaggi')
    .description('Legge il file messaggi')
    .action(function (args, callback) {
        var contents = fs.readFileSync("messaggi.json");
        messaggi = JSON.parse(contents);
        callback();
    });

vorpal
    .command('file scrivi messaggi')
    .description('Scrive il file messaggi')
    .action(function (args, callback) {
        var jsontostring = JSON.stringify(messaggi);
        fs.writeFile('messaggi.json', jsontostring, function (err) {
            if (err) {
                return console.error(err);
            }
        });
        callback();
    });

// leggi file , scrivi file

vorpal
    .delimiter(chalk.yellow('messaggi$'))
    .show();




const validate = function (request, username, password, callback) {
    loggato = false;


    utenti.forEach(element => {
        if ((element.name == username) && (element.pass == password)) {
            loggato = true;
            console.log("Accesso effettuato");
            return callback(null, true, {
                name: username
            })
        }
    });
    if (!loggato)
        return callback(null, false);
};

server.register(Basic, function (err) {
    if (err) {
        throw err;
    }
});

server.auth.strategy('simple', 'basic', {
    validateFunc: validate
});



server.route({
    method: 'GET',
    path: '/',
    config: {
        auth: 'simple',
        handler: function (request, reply) {
            reply('hello, ' + request.auth.credentials.name);
        }
    }
});

//route scrivere
server.route({
    method: 'POST',
    path: '/invia',
    config: {
        auth: 'simple',
        handler: function (request, reply) {
            //console.log("Received POST from " + request.payload.name + "; id=" + (request.payload.id || 'anon'));
            var payload = encodeURIComponent(request.payload)
            console.log(request.payload);
            console.log(request.payload.dest);
            console.log(request.payload.messaggio);
            messaggi.push({
                destinazione: request.payload.dest,
                sorgente: request.auth.credentials.name,
                messsaggio: request.payload.messaggio
            });
            var jsontostring = JSON.stringify(messaggi);
            fs.writeFile('messaggi.json', jsontostring, function (err) {
                if (err) {
                    return console.error(err);
                }
            });
            console.log(messaggi);
            reply(messaggi[messaggi.length - 1]);

        }
    }
});


//route leggere (json)
server.route({
    method: 'GET',
    path: '/messaggi',
    config: {
        auth: 'simple',
        handler: function (request, reply) {
            messaggi = fs.readFileSync("messaggi.json");
            var estratti = messaggi.filter(function (element) {
                return element.destinazione == request.auth.credentials.name;
            });
            var s = [];

            console.log(request.auth.credentials.name);
            console.log(estratti.length);
            estratti.forEach(element => {

                s.push(element);

                //fare l'array con stringify
                //s+="mittente : "+element.sorgente+": "+element.messsaggio+"\n";

            });
            var a = JSON.stringify(s);
            console.log(a);
            console.log(s);
            reply(a);
        }
    }
});



server.start(function () {
    console.log('Hapi is listening to ' + server.info.uri);
});

function EseguiSql(connection, sql, reply) {
    var rows = [];
    request = new Request(sql, function (err, rowCount) {
        if (err) {
            console.log(err);
        } else {
            console.log(rowCount + ' rows');
            console.log("Invio Reply")
            reply(rows);
        }
    });

    request.on('row', function (columns) {
        var row = {};
        columns.forEach(function (column) {
            row[column.metadata.colName] = column.value;
        });
        rows.push(row);
    });

    connection.execSql(request);
}

server.route({
    method: 'POST',
    path: '/query',
    handler: function (request, reply) {
        // Qui dovrebbe cercare i dati nel body e rispondere con la query eseguita
        var connection = new Connection(config);

        // Attempt to connect and execute queries if connection goes through
        connection.on('connect', function (err) {
            if (err) {
                console.log(err);
            } else {

                console.log('Connected');
                console.log(request.payload.sql);
                EseguiSql(connection, request.payload.sql, reply);
            }
        });

    }
});

server.connection({
    host: process.env.HOST || 'localhost',
    port: process.env.PORT || 8080
});

var config = {
    userName: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    server: process.env.DB_SERVER,
    options: {
        database: process.env.DB_NAME,
        encrypt: true
    }
}

Chào mừng bạn đến với StackOverflow. Bạn có thể giải thích rõ hơn về câu trả lời của bạn và nó liên quan đến câu hỏi được đăng bởi OP như thế nào không?
Szymon Maszke

-3
    const Hapi = require('hapi');
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
const server = new Hapi.Server();
var vorpal = require('vorpal')();

server.connection({
    host: process.env.HOST || 'localhost',
    port: process.env.PORT || 3000
});
server.start(function (err) {
    if (err) {
        throw err;
    }
    console.log("server running at : " + server.info.uri);
});

var config =
{
    userName: 'sa',
    password: 'password.123',
    server: 'localhost',

    options:
    {
        database: '',
        port: 1433
    }
}

server.route(
    {
        method: 'GET',
        path: '/{categoria}',
        handler: function (request, reply) {
            var connection = new Connection(config);
            connection.on('connect', function (err) {
                if (err) {
                    console.log(err);
                }
                else {
                    console.log('Connected');
                    EseguiSqlGet(connection, request.params.categoria, reply);
                }
            });
        }
    }
);
function EseguiSqlGet(connection, cat, reply) {
    var rows = [];
    var sql = 'SELECT * FROM Prodotti INNER JOIN Categorie
 on Categorie.IdCategoria = Prodotti.IdCategoria
 WHERE Categorie.IdCategoria = ' + cat ;
    request_sql = new Request(sql, function(err, rowCount) {
        if (err) {
            console.log(err);
        } else {
            console.log(rowCount + ' rows');
            console.log("Invio Reply")
            reply(rows);
        }
    });

    request_sql.on('row', function(columns) {
        var row = {};
        columns.forEach(function (column) {
            row[column.metadata.colName] = column.value;
        });
        rows.push(row);
    });

    connection.execSql(request_sql);
}
// POST
server.route(
    {
        method: 'POST',
        path: '/inserisci',
        handler: function (request, reply) {
            var connection = new Connection(config);
            connection.on('connect', function (err) {
                if (err) {
                    console.log(err);
                }
                else {
                    console.log('Connected');
                    EseguiSqlPost(connection,reply, 
request.payload.idcat, request.payload.nome, request.payload.prezzo );
                }
            });
        }
    }
);
function EseguiSqlPost(connection,reply, cat,nome,prezzo) {

    var sql = "INSERT INTO Prodotti
 VALUES("+ cat +",'"+nome+"',"+prezzo+")";
    request_sql = new Request(sql, function(err, rowCount) {
        if (err) {
            console.log(err);
        } else {
            console.log(rowCount + ' rows');
            console.log("Invio Reply")
            reply('riga aggiunta');
        }
    });

    /*request_sql.on('row', function(columns) {
        var row = {};
        columns.forEach(function (column) {
            row[column.metadata.colName] = column.value;
        });
        rows.push(row);
    });
*/
    connection.execSql(request_sql);
}






//VORPAL COMMAND PROMT
var categoria = [
    {

        'idcategoria':'1',
        'nome':'ciao',

    }
]


vorpal
    .command('inserisci <categoria> <nome>')
    .action(function(args, callback)
    {
        categoria.push(   
{'idcategoria':args.categoria,'nome':args.nome}     );
        console.log(JSON.stringify(categoria));
        callback();
    });

vorpal
.delimiter("delimeter")
.show();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.