Skip to content

Commit daf9a87

Browse files
committed
Initial mess
0 parents  commit daf9a87

29 files changed

+1133
-0
lines changed

.gitignore

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/.bundle/
2+
/.yardoc
3+
/_yardoc/
4+
/coverage/
5+
/doc/
6+
/pkg/
7+
/spec/reports/
8+
/tmp/
9+
Gemfile.lock
10+
.rubocop-*

.rspec

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--require spec_helper

.rubocop.yml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Please keep AllCops, Bundler, Layout, Style, Metrics groups and then order cops
2+
# alphabetically
3+
#
4+
# References:
5+
# * https://github.com/bbatsov/ruby-style-guide
6+
# * https://rubocop.readthedocs.io/
7+
inherit_from:
8+
- https://raw.githubusercontent.com/hanami/devtools/master/.rubocop-unstable.yml
9+
AllCops:
10+
TargetRubyVersion: 2.7

Gemfile

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# frozen_string_literal: true
2+
3+
source "https://rubygems.org"
4+
gemspec
5+
6+
gem "byebug", require: false
7+
gem "hanami-router", git: "https://github.com/hanami/router.git", branch: "feature/tree-rewrite"

README.md

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Hanami::Api
2+
3+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/hanami/api`. To experiment with that code, run `bin/console` for an interactive prompt.
4+
5+
TODO: Delete this and the text above, and describe your gem
6+
7+
## Installation
8+
9+
Add this line to your application's Gemfile:
10+
11+
```ruby
12+
gem 'hanami-api'
13+
```
14+
15+
And then execute:
16+
17+
$ bundle install
18+
19+
Or install it yourself as:
20+
21+
$ gem install hanami-api
22+
23+
## Usage
24+
25+
TODO: Write usage instructions here
26+
27+
## Development
28+
29+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30+
31+
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).
32+
33+
## Contributing
34+
35+
Bug reports and pull requests are welcome on GitHub at https://github.com/jodosha/hanami-api.
36+

Rakefile

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# frozen_string_literal: true
2+
3+
require "rake"
4+
require "bundler/gem_tasks"
5+
require "rspec/core/rake_task"
6+
7+
RSpec::Core::RakeTask.new(:spec) do |task|
8+
file_list = FileList["spec/**/*_spec.rb"]
9+
10+
task.pattern = file_list
11+
end
12+
13+
task default: "spec"

bin/console

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
require "bundler/setup"
5+
require "hanami/api"
6+
7+
# You can add fixtures and/or initialization code here to make experimenting
8+
# with your gem easier. You can also use a different console, if you like.
9+
10+
# (If you use this, don't forget to add pry to your Gemfile!)
11+
# require "pry"
12+
# Pry.start
13+
14+
require "irb"
15+
IRB.start(__FILE__)

bin/setup

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
IFS=$'\n\t'
4+
set -vx
5+
6+
bundle install
7+
8+
# Do any other automated setup that you need to do here

hanami-api.gemspec

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# frozen_string_literal: true
2+
3+
require_relative "lib/hanami/api/version"
4+
5+
Gem::Specification.new do |spec|
6+
spec.name = "hanami-api"
7+
spec.version = Hanami::API::VERSION
8+
spec.authors = ["Luca Guidi"]
9+
spec.email = ["me@lucaguidi.com"]
10+
11+
spec.summary = "Hanami API"
12+
spec.description = "Extremely fast and lightweight HTTP API"
13+
spec.homepage = "http://rubygems.org"
14+
spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
15+
16+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
17+
18+
spec.metadata["homepage_uri"] = spec.homepage
19+
spec.metadata["source_code_uri"] = "https://github.com/hanami/api"
20+
spec.metadata["changelog_uri"] = "https://github.com/hanami/api/blob/master/CHANGELOG.md"
21+
22+
# Specify which files should be added to the gem when it is released.
23+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
25+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26+
end
27+
28+
spec.bindir = "exe"
29+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30+
spec.require_paths = ["lib"]
31+
32+
spec.add_dependency "hanami-router", "~> 2.0.alpha"
33+
34+
spec.add_development_dependency "rake", "~> 13.0"
35+
spec.add_development_dependency "rspec", "~> 3.8"
36+
spec.add_development_dependency "rubocop", "~> 0.79"
37+
end

lib/hanami/api.rb

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# frozen_string_literal: true
2+
3+
module Hanami
4+
# Hanami::API
5+
#
6+
# @since 0.1.0
7+
class API
8+
require "hanami/api/version"
9+
require "hanami/api/error"
10+
require "hanami/api/router"
11+
require "hanami/api/middleware"
12+
13+
def self.inherited(app)
14+
super
15+
16+
app.class_eval do
17+
@routes = []
18+
@stack = Middleware::Stack.new
19+
end
20+
end
21+
22+
class << self
23+
attr_reader :routes, :stack
24+
end
25+
26+
def self.root(*args, **kwargs, &blk)
27+
@routes << [:root, args, kwargs, blk]
28+
end
29+
30+
def self.get(*args, **kwargs, &blk)
31+
@routes << [:get, args, kwargs, blk]
32+
end
33+
34+
def self.post(*args, **kwargs, &blk)
35+
@routes << [:post, args, kwargs, blk]
36+
end
37+
38+
def self.patch(*args, **kwargs, &blk)
39+
@routes << [:patch, args, kwargs, blk]
40+
end
41+
42+
def self.put(*args, **kwargs, &blk)
43+
@routes << [:put, args, kwargs, blk]
44+
end
45+
46+
def self.delete(*args, **kwargs, &blk)
47+
@routes << [:delete, args, kwargs, blk]
48+
end
49+
50+
def self.trace(*args, **kwargs, &blk)
51+
@routes << [:trace, args, kwargs, blk]
52+
end
53+
54+
def self.options(*args, **kwargs, &blk)
55+
@routes << [:options, args, kwargs, blk]
56+
end
57+
58+
def self.link(*args, **kwargs, &blk)
59+
@routes << [:link, args, kwargs, blk]
60+
end
61+
62+
def self.unlink(*args, **kwargs, &blk)
63+
@routes << [:unlink, args, kwargs, blk]
64+
end
65+
66+
def self.redirect(*args, **kwargs, &blk)
67+
@routes << [:redirect, args, kwargs, blk]
68+
end
69+
70+
def self.scope(*args, **kwargs, &blk)
71+
@routes << [:scope, args, kwargs, blk]
72+
end
73+
74+
def self.mount(*args, **kwargs, &blk)
75+
@routes << [:mount, args, kwargs, blk]
76+
end
77+
78+
def self.use(middleware, *args, &blk)
79+
@stack.use(middleware, args, &blk)
80+
end
81+
82+
def initialize(routes: self.class.routes, stack: self.class.stack)
83+
@stack = stack
84+
@router = Router.new(stack: @stack) do
85+
routes.each do |method_name, args, kwargs, blk|
86+
send(method_name, *args, **kwargs, &blk)
87+
end
88+
end
89+
90+
freeze
91+
end
92+
93+
def freeze
94+
@app = @stack.finalize(@router)
95+
remove_instance_variable(:@stack)
96+
@router.freeze
97+
super
98+
end
99+
100+
def call(env)
101+
@app.call(env)
102+
end
103+
104+
# TODO: verify if needed here on in block context
105+
def path(name, variables = {})
106+
@router.path(name, variables)
107+
end
108+
109+
# TODO: verify if needed here on in block context
110+
def url(name, variables = {})
111+
@router.url(name, variables)
112+
end
113+
end
114+
end

lib/hanami/api/block/context.rb

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# frozen_string_literal: true
2+
3+
require "hanami/router/block"
4+
require "rack/utils"
5+
require "json"
6+
7+
module Hanami
8+
class API
9+
module Block
10+
class Context < Hanami::Router::Block::Context
11+
def body(value = nil)
12+
if value
13+
@body = value
14+
else
15+
@body
16+
end
17+
end
18+
19+
def halt(status, body = nil)
20+
body ||= http_status(status)
21+
throw :halt, [status, body]
22+
end
23+
24+
def redirect(url, status = 301)
25+
headers["Location"] = url
26+
halt(status)
27+
end
28+
29+
def back
30+
env["HTTP_REFERER"] || "/"
31+
end
32+
33+
def json(object, mime = "application/json")
34+
headers["Content-Type"] = mime
35+
JSON.generate(object)
36+
end
37+
38+
def call
39+
case caught
40+
in String => body
41+
[status, headers, [body]]
42+
in Integer => status
43+
[status, headers, [self.body || http_status(status)]]
44+
in [Integer, String] => response
45+
[response[0], headers, [response[1]]]
46+
in [Integer, Hash, String] => response
47+
headers.merge!(response[1])
48+
[response[0], headers, [response[2]]]
49+
end
50+
end
51+
52+
private
53+
54+
def caught
55+
result = nil
56+
halted = catch :halt do
57+
result = instance_exec(&@blk)
58+
nil
59+
end
60+
61+
halted || result
62+
end
63+
64+
def http_status(code)
65+
Rack::Utils::HTTP_STATUS_CODES.fetch(code)
66+
end
67+
end
68+
end
69+
end
70+
end

lib/hanami/api/error.rb

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# frozen_string_literal: true
2+
3+
module Hanami
4+
class API
5+
class Error < StandardError
6+
end
7+
end
8+
end

0 commit comments

Comments
 (0)