Khi mới học Rails, Rack thường xuất hiện trong Gemfile như một người họ hàng ít nói: luôn có mặt nhưng chẳng ai giải thích. Thực ra contract của Rack rất nhỏ.
Một Rack application là object respond to call và nhận env:
1 | class App |
Response có ba phần:
- HTTP status integer.
- Headers dạng hash.
- Body là object có thể
eachvà yield string.
Chạy application
1 | # config.ru |
1 | bundle exec rackup |
Rack adapter nhận request từ web server, xây env, gọi application và chuyển tuple response trở lại HTTP. Rack không dịch “thứ app server hiểu” sang “thứ Rails hiểu” theo kiểu phép thuật; nó định nghĩa interface chung để server và framework nói cùng protocol.
Đọc request
Đừng tự parse QUERY_STRING hoặc eval dữ liệu từ file/request. eval biến input thành Ruby code—một feature khá mạnh nếu mục tiêu là trao server cho người lạ.
1 | require "rack" |
Middleware
Middleware cũng là Rack app, nhưng giữ reference tới app tiếp theo:
1 | class RequestTimer |
1 | # config.ru |
Rails request đi qua một stack middleware cho logging, cookies, sessions, exceptions, security headers và nhiều việc khác trước khi tới controller.
Rack đáng học không phải vì ta sẽ bỏ Rails để tự viết framework vào cuối tuần. Nó cho thấy boundary thật sự: env vào, response ba phần ra, middleware bao quanh. Phần còn lại là abstraction—rất hữu ích, nhưng không còn là phép màu.