Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/rack-app/rack-app
minimalist framework for building rack applications
https://github.com/rack-app/rack-app
api rack rack-apps ruby ruby-framework web-app web-application-framework web-application-frameworks
Last synced: 11 days ago
JSON representation
minimalist framework for building rack applications
- Host: GitHub
- URL: https://github.com/rack-app/rack-app
- Owner: rack-app
- License: apache-2.0
- Created: 2015-10-03T10:11:18.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2023-11-15T19:08:48.000Z (12 months ago)
- Last Synced: 2024-09-19T15:18:11.326Z (about 2 months ago)
- Topics: api, rack, rack-apps, ruby, ruby-framework, web-app, web-application-framework, web-application-frameworks
- Language: Ruby
- Homepage:
- Size: 1.8 MB
- Stars: 410
- Watchers: 17
- Forks: 21
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# [Rack::App](https://github.com/rack-app/rack-app)
![rack-app-logo](/assets/rack-app-logo.png)
[rack-app GPT assistant](https://chat.openai.com/g/g-DOKIpY8aq-rack-app)
`rack-app` is a minimalist web framework that focuses on simplicity and maintainability.
The framework is meant to be used by seasoned web developers.`rack-app` focus on keeping the dependencies as little as possible,
while allowing writing functional and minimalist rack-based applications,
that will do nothing more than what you defined.The routing uses a prefix tree,
thus adding a large number of API endpoints won't affect the routing lookup time.It was inspirited by `Sinatra`, `grape`, and `rack`.
It's used in production, powering back-end APIs running on the public cloud.## Development Status
The framework is considered stable.
I don't have the plan to feature creep the framework without real-life use-cases,
since most of the custom edge cases can be resolved with composition.The next time it will receive further updates,
when rack provides a finalized support for http2.If you have an issue, I weekly check the issues tab,
answer and reply, or implement a fix for it.Since the framework's only dependency is the `rack` gem,
I don't have to update the codebase too often.Cheers and Happy Coding!
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'rack-app'
```And then execute:
$ bundle
Or install it yourself as:
$ gem install rack-app
## Is it Production ready?
Yes, it's already powering Heroku hosted micro-services.
## Principles
* Keep It Simple
* No Code bloat
* No on run time processing, or keep at the bare minimum
* Fully BDD (Behaviour Driven Design)
* built-in test module to ease the development with easy to use tests
* Easy to Learn
* rack-app use well known and easy to understand conventions, such as sinatra like DSL
* Principle Of Least Surprise
* Modular design
* the Only dependency is rack, nothing more
* Open development
* Try to create Examples for every feature## Features
* Easy to understand syntax
* module method level endpoint definition inspirited heavily by the Sinatra DSL
* unified error handling
* syntax sugar for default header definitions
* namespaces for endpoint request path declarations so it can be dry and unified
* no Class method bloat, so you can enjoy pure ruby without any surprises
* App mounting so you can create separated controllers for different task
* Streaming
* O(log(n)) lookup routing
* allows as many endpoint registrations to you as you want, without impact on route lookup speed
* only basic sets for instance method level for the must need tools, such as params, payload
* Simple to use class level response serializer
* so you can choose what type of serialization you want without any enforced convention
* static file serving so you can mount even filesystem-based endpoints too
* built-in testing module so your app can be easily written with BDD approach
* made with minimalism in mind so your app can't rely on the framework when you implement business logic
* if you need something, you should implement it without any dependency on a web framework, rack-app only mean to be to provide you with easy to use interface to the web layer, nothing less and nothing more
* per endpoint middleware definitions
* you can define middleware stack before endpoints and it will only apply to them, similar like protected method workflow
* File Upload and file download efficiently and elegantly with minimal memory consuming
* note that this is not only memory friendly way pure rack solution, but also 2x faster than the usual solution which includes buffering in memory
* params validation with ease## Under the hood
rack-app's router relies on a tree structure which makes heavy use of *common prefixes*,
it is basically a *compact* [*prefix tree*](https://en.wikipedia.org/wiki/Trie) (or just [*Radix tree*](https://en.wikipedia.org/wiki/Radix_tree)).
Nodes with a common prefix also share a common parent.## Contributors
* **[Daniel Nagy](https://github.com/thilonel)**
* Serializer MVP implementation
* **[Daniel Szpisjak](https://github.com/felin-arch)**
* Pimp up the website descriptions
* **[Jeremy Evans](https://github.com/jeremyevans)**
* suggestion for application stand up speed optimization
* **[David Bush](https://github.com/disavowd)**
* [wrote an awesome article](https://www.sitepoint.com/rack-app-a-performant-and-pragmatic-web-microframework/) about the project
* **[TheSmartnik](https://github.com/TheSmartnik)**
* Clarify examples in the documentation
## [Contributing](CONTRIBUTING.md)
## Usage
#### basic
```ruby
require 'rack/app'
class App < Rack::App
desc 'some hello endpoint'
get '/hello' do
'Hello World!'
endend
```
#### complex
```ruby
require 'rack/app'
class App < Rack::App
mount SomeAppClass
headers 'Access-Control-Allow-Origin' => '*',
'Access-Control-Expose-Headers' => 'X-My-Custom-Header, X-Another-Custom-Header'serializer do |object|
object.to_s
enddesc 'some hello endpoint'
validate_params do
required 'words', :class => Array, :of => String, :desc => 'some word', :example => ['pug']
optional 'word', :class => String, :desc => 'one word', :example => 'pug'
optional 'boolean', :class => :boolean, :desc => 'boolean value', :example => true
end
get '/hello' do
puts(params['words'])'Hello World!'
endnamespace '/users' do
desc 'some restful endpoint'
get '/:user_id' do
response.status = 201
params['user_id'] #=> restful parameter :user_id
say #=> "hello world!"
endend
desc 'some endpoint that has error and will be rescued'
get '/make_error' do
raise(StandardError,'error block rescued')
enddef say
"hello #{params['user_id']}!"
enderror StandardError, NoMethodError do |ex|
{:error=>ex.message}
endroot '/hello'
get '/stream' do
stream do |out|
out << 'data row'
end
endend
```
you can access Rack::Request with the request method and
Rack::Response as a response method.By default, if you don't write anything to the response 'body' the endpoint block logic return will be used
### Frontend Example
if you don't mind extending your dependency list then you can use the front_end extension for creating template-based web applications.
```ruby
require 'rack/app'
require 'rack/app/front_end' # You need to add `gem 'rack-app-front_end'` to your Gemfileclass App < Rack::App
apply_extensions :front_end
helpers do
def method_that_can_be_used_in_template
'hello world!'
endend
# use ./app/layout.html.erb as layout, this is optionable
layout 'layout.html.erb'# at '/' the endpoint will serve (render)
# the ./app/index.html content as response body and wrap around with layout if the layout is given
get '/' do
render 'index.html'
endend
```this example expects an "app" folder next to the "app.rb" file that included templates being used such as layout.html.erb and index.html.
## Testing
for testing use rack/test or the bundled testing module for writing unit test for your rack application
```ruby
require 'spec_helper'
require 'rack/app/test'describe App do
include Rack::App::Test
rack_app described_class
describe '/hello' do
# example for params and headers and payload use
subject { get(url: '/hello', params: {'dog' => 'meat'}, headers: {'X-Cat' => 'fur'}, payload: 'some string') }it { expect(subject.status).to eq 200 }
it { expect(subject.body).to eq "Hello World!" }
enddescribe '/users/:user_id' do
# restful endpoint example
subject { get(url: '/users/1234') }it { expect(subject.body).to eq 'hello 1234!'}
it { expect(subject.status).to eq 201 }
end
describe '/make_error' do
# error handled example
subject { get(url: '/make_error') }it { expect(subject.body).to eq '{:error=>"error block rescued"}' }
endend
```
## Example Apps To start with
* [Official website How To examples](https://github.com/rack-app/rack-app/wiki)
* [Rack::App Team Github repositories](https://github.com/rack-app)
* [Basic](https://github.com/rack-app/rack-app-example-basic)
* bare-bone simple example app* [Escher Authorized Api](https://github.com/rack-app/rack-app-example-escher)
* complex authorization for corporal level API use## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
## Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/rack-app/rack-app This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
## License and Copyright
Rack::App is free software released under the [Apache License V2](https://opensource.org/licenses/Apache-2.0) License.
The logo was designed by Zsófia Gebauer. It is Copyright © 2015 Adam Luzsi. All Rights Reserved.