Toycol
Toycol is a small framework for defining toy application protocols.
You can define your own application protocol only by writing a parser in Toycol DSL for request messages.
Since the server and client programs to run the protocol are built-in from the beginning, you only need to prepare the following two items to run your custom protocol.
- A configuration file named like
Protocolfile
,Protocolfile.protocol_name
and so on - A Rack compartible application(e.g.
config.ru
)
In the real world, there is (yet) no full-fledged web server or browser in the world that runs on the custom protocol you devised. Therefore, the protocol defined by this framework is in fact a "toy". However, by using this framework, you will be able to experience and learn how the connection between the application layer and the transport layer is, and how the application protocol works on the transport layer.
Example(on original "Duck" protocol)
In this protocol:
- Client would send message like:
"quack, quack /posts<3user_id=1"
- Server would interpret client message:
"GET /posts?user_id=1"
You write your definition in Protocolfile
# Protocolfile.duck (protocol file)
Protocol.define(:duck) do
# [OPTIONAL] You can add your original request methods
add_request_methods "OTHER"
# [OPTIONAL] You can define your custom status codes
custom_status_codes(
600 => "I'm afraid you are not a duck..."
)
# [REQUIRED] Define how you parse request path from request message
request.path do |message|
%r{(?<path>\/\w*)}.match(message)[:path]
end
# [REQUIRED] Define how you parse query from request message
request.query do |message|
%r{\<3(?<query>.+)}.match(message) { |m| m[:query] }
end
# [REQUIRED] Define how you parse query from request message
request.http_method do |message|
case message.scan(/quack/).size
when 2 then "GET"
else "OTHER"
end
end
end
Don't forget, you need to prepare your application as well.
# config_duck.ru (Rack compartible application)
require "rack"
require "toycol"
# Specify which protocol to use
Toycol::Protocol.use(:duck)
class App
def call(env)
case env["REQUEST_METHOD"]
when "GET"
[
200,
{ "Content-Type" => "text/html" },
["Quack, Quack! This app is running by Duck protocol."]
]
when "OTHER"
[
600,
{ "Content-Type" => "text/html" },
["Sorry, this application is only for ducks...\n"]
]
end
end
end
run App.new
Then you run server & client
# In terminal for server
$ toycol server config_duck.ru
Toycol starts build-in server, listening on unix:///tmp/toycol.socket
Toycol is running on localhost:9292
=> Use Ctrl-C to stop
# In other terminal for client
$ toycol client "quack, quack /posts<3user_id=1"
[Toycol] Sent request message: quack, quack /posts<3user_id=1
---
[Toycol] Received response message:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 32
Quack, Quack! This app is running by Duck protocol.
Installation
Add this line to your application's Gemfile:
gem "toycol"
And then execute:
$ bundle install
Or install it yourself as:
$ gem install toycol
Usage
Toycol provides useful commands to define & run your protocol.
toycol generate
- To define your new protocol
You can use toycol generate
command to generate skeletons of Protocolfile and application.
$ toycol generate PROTOCOL_NAME
When you run this command, skeletons of Protocolfile.PROTOCOL_NAME
and config_PROTOCOL_NAME.ru
will be generated.
If you only need one of them, you can specify the type by -t
option.
$ toycol generate PROTOCOL_NAME -t protocol
# or
$ toycol generate PROTOCOL_NAME -t app
If PROTOCOL_NAME
is not specified, Protocolfile and config.ru will simply be generated.
$ toycol generate
toycol server
- To run server by your protocol
After you prepare Protocolfile & application, you need to start server to run the application by toycol server
command.
# Please specify application file name
$ toycol server config_`PROTOCOL_NAME`.ru
Then the server will start.
Normally, toycol server
command will start the server built into toycol.
However, if Puma is already installed in your environment, it will start Puma by default.
If you want to explicitly specify which server to use, you can use the -u option.
$ toycol server config_`PROTOCOL_NAME`.ru -u puma
# or
$ toycol server config_`PROTOCOL_NAME`.ru -u buid_in
If you would like to check other options, run the command toycol server -h
.
toycol client
- To send request message by your protocol
When you would like to send the request message to the server, use toycol client
.
$ toycol client "YOUR REQUEST MESSAGE"
If you would like to check other options, run the command toycol client -h
.
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake test
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 the created tag, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/shioimm/toycol. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the Toycol project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.