{"id":20636820,"url":"https://github.com/tombenner/noder","last_synced_at":"2025-10-08T04:35:53.282Z","repository":{"id":16983540,"uuid":"19746377","full_name":"tombenner/noder","owner":"tombenner","description":"Node.js for Ruby","archived":false,"fork":false,"pushed_at":"2015-01-02T15:36:12.000Z","size":164,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-05T01:31:00.583Z","etag":null,"topics":["node","ruby"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tombenner.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-05-13T16:15:49.000Z","updated_at":"2024-09-20T19:59:52.000Z","dependencies_parsed_at":"2022-07-26T11:47:13.517Z","dependency_job_id":null,"html_url":"https://github.com/tombenner/noder","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tombenner/noder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tombenner%2Fnoder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tombenner%2Fnoder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tombenner%2Fnoder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tombenner%2Fnoder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tombenner","download_url":"https://codeload.github.com/tombenner/noder/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tombenner%2Fnoder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278872154,"owners_count":26060525,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["node","ruby"],"created_at":"2024-11-16T15:12:14.764Z","updated_at":"2025-10-08T04:35:53.255Z","avatar_url":"https://github.com/tombenner.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"Noder\n=====\nNode.js for Ruby\n\nOverview\n--------\n\nNoder brings the architecture of Node.js to Ruby. It focuses on the implementation of Node.js's HTTP-related support, as Ruby's standard library and other gems already provide great analogs of many of Node.js's other core modules.\n\nYou may also be interested in [Expressr](https://github.com/tombenner/expressr) (Express.js for Ruby), which Noder was built to support, and [EM-Synchrony](https://github.com/igrigorik/em-synchrony). Noder runs on [EventMachine](https://github.com/eventmachine/eventmachine).\n\nExample\n-------\n\nA web server can be created and started using the following script:\n\n```ruby\nrequire 'noder'\n\nserver = Noder::HTTP::Server.new do |request, response|\n  response.write_head(200, { 'Content-Type' =\u003e 'text/plain' })\n  response.end('Hello world!')\nend\nserver.listen(1337, '127.0.0.1')\n```\n\nTo start the app, put the code into a file named `my_server.rb` and run it:\n\n```bash\n$ ruby my_server.rb\nRunning Noder at 127.0.0.1:1337...\n```\n\nAPI\n---\n\n* [HTTP](#http)\n  * [Server](#noderhttpserver)\n  * [Request](#noderhttprequest)\n  * [Response](#noderhttpresponse)\n* [Events](#events)\n  * [EventEmitter](#nodereventseventemitter)\n\nHTTP\n----\n\n### Noder::HTTP::Server\n\n`Noder::HTTP::Server` lets you create and run HTTP servers.\n\n#### .new(options={}, \u0026block)\n\nCreates the server.\n\n##### options\n\n* `:address` - The server's address (default: `'0.0.0.0'`)\n* `:port` - The server's port (default: `8000`)\n* `:environment` - The server's environment name (default: `'development'`)\n* `:threadpool_size` - The size of the server's threadpool (default: `20`)\n* `:enable_ssl` - A boolean of whether SSL is enabled (default: `false`)\n* `:ssl_key` - A filepath to the SSL key (default: `nil`)\n* `:ssl_cert` - A filepath to the SSL cert (default: `nil`)\n\n##### \u0026block\n\nA block that will be called for every request. It will be passed the request (a Noder::HTTP::Request) and response (a Noder::HTTP::Response) as arguments.\n\n#### #listen(port=nil, address=nil, options={}, \u0026block)\n\nStarts accepting connections to the server. `options` are the same as the options in `.new`, and `\u0026block` behaves the same as in `.new`.\n\n```ruby\nserver = Noder::HTTP::Server.new\nserver.listen(8001) do |request, response|\n  response.write(\"Hello world!\")\n  response.end\nend\n```\n\n#### #close\n\nStops the server. This is called when an `INT` or `TERM` signal is sent to a running server's process (e.g. when `Control-C` is pressed).\n\n#### Event 'request'\n\nEmitted for every request. The request and response are passed as arguments.\n\n```ruby\nserver.on('request') do |request, response|\n  Noder.logger.info \"Request params: #{request.params}\"\n  response.set_header('MyHeader', 'My value')\nend\n```\n\n#### Event 'close'\n\nEmitted when the server is closing. No arguments are passed.\n\n```ruby\nserver.on('close') do\n  Noder.logger.info \"Stopping server...\"\nend\n```\n\n### Noder::HTTP::Request\n\nA representation of an HTTP request.\n\n#### #params\n\nA hash of the request's params (the query string and POST data). The hash's keys are strings (e.g. `/?foo=bar` yields `{ 'foo' =\u003e 'bar' }`)\n\n#### #headers\n\nA hash of the request's headers (e.g. `{ 'Accept' =\u003e '*/*', 'User-Agent' =\u003e 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) [...]' }`).\n\n#### #request_method\n\nThe request's verb (e.g. `'GET'`, `'POST'`, etc).\n\n#### #cookie\n\nThe request's Cookie header (e.g. `'my_cookie=123; my_other_cookie=foo'`).\n\n#### #content_type\n\nThe request's Content-Type header (e.g. `'application/x-www-form-urlencoded'`).\n\n#### #request_uri\n\nThe request's path, without the query string (e.g. `'/users/1/profile'`).\n\n#### #query_string\n\nThe request's query string (e.g. `/about?foo=bar\u0026baz=1` yields `'foo=bar\u0026baz=1'`).\n\n#### #protocol\n\nThe request's protocol (e.g. `'HTTP/1.1'`).\n\n#### #ip\n\nThe client's IP address (e.g. `'68.1.8.45'`).\n\n### Noder::HTTP::Response\n\nA representation of an HTTP response.\n\n#### #write(content)\n\nWrites the content to the response's body.\n\n```ruby\nresponse.write('Hello world!')\n```\n\n#### #write_head(status, headers={})\n\nSets the response's status code and sets the specified headers (if any).\n\n```ruby\nresponse.write_head(500, { 'MyHeader' =\u003e 'My value' })\n```\n\n#### #status_code\n\nGets or sets the response's status code\n\n```ruby\nresponse.status_code # 200\nresponse.status_code = 500\n```\n\n#### #set_header(name, value)\n\nSets the specified header.\n\n```ruby\nresponse.set_header('MyHeader', 'My value')\n```\n\n#### #get_header(name, value)\n\nGets the specified header.\n\n```ruby\nresponse.get_header('MyHeader') # 'My value'\n```\n\n#### #remove_header(name)\n\nGets the specified header.\n\n```ruby\nresponse.remove_header('MyHeader')\n```\n\n#### #end(content=nil)\n\nSends the response. This must be called on every response instance.\n\nIf `content` is provided, it is equivalent to calling `write(content)` followed by `end`.\n\nEvents\n------\n\n### Noder::Events::EventEmitter\n\nInclude `Noder::Events::EventEmitter` in classes which should manage events. For example:\n\n```ruby\nclass MyServer\n  include Noder::Events::EventEmitter\n\n  def initialize(\u0026block)\n    on('start', \u0026block)\n    on('stop', proc { puts 'Stopping...' })\n  end\n\n  def run\n    emit('start')\n    emit('stop')\n  end\nend\n\nserver = MyServer.new do\n  puts 'Starting up...'\nend\nserver.on('start') do\n  puts 'Still starting up...'\nend\n\nserver.run\n# Starting up...\n# Still starting up...\n# Stopping...\n```\n\n#### #on(event, callback=nil, options={}, \u0026block)\n\nAdds a listener to the specified event. The listener can either be an instance of a Proc (as the `callback` argument) or a block.\n\n`add_listener` is an alias of `on`.\n\n#### #emit(event)\n\nCall the listeners for the specified event.\n\n#### #remove_listener(event, listener)\n\nRemove the listener. Listeners are compared using the `==` operator.\n\n```ruby\nlistener = proc { puts 'Working...' }\nserver.on('start', listener)\nserver.remove_listener('start', listener)\n```\n\n#### #remove_all_listeners(event)\n\nRemoves all of the listeners from the event. You probably don't want to call this on core Noder events.\n\n```ruby\nserver.remove_all_listeners('start')\n```\n\n#### #set_max_listeners(event, count)\n\nSets the maximum number of listeners for the specified event. A warning will be logged every time any additional listeners are added.\n\n```ruby\nserver.set_max_listeners('start', 100)\n```\n\n#### #listeners(event)\n\nReturns an array of the listeners for the specified event.\n\n```ruby\nserver.listeners('start')\n```\n\n#### #listener_count(event)\n\nReturns the number of listeners for the specified event.\n\n```ruby\nserver.listener_count('start')\n```\n\nLogging\n-------\n\nNoder's `Logger` is available at `Noder.logger`. You can write to it:\n\n```ruby\nNoder.logger.debug 'My debug message...'\nNoder.logger.error 'My error message...'\n```\n\nYou can modify it or replace it if you like, too:\n\n```ruby\n# Adjust attributes of the logger\nNoder.logger.level = Logger::DEBUG\n\n# Or create a custom Logger\nNoder.logger = Logger.new(STDOUT)\nNoder.logger.level = Logger::DEBUG\n```\n\nSee the [Logger docs](http://www.ruby-doc.org/stdlib-2.0/libdoc/logger/rdoc/Logger.html) for more.\n\nHTTPS\n-----\n\nTo support HTTPS, set `:enable_ssl` to `true` and set the `:ssl_key` and `:ssl_cert` values to the appropriate file paths:\n\n```ruby\noptions = {\n  enable_ssl: true,\n  ssl_key: File.expand_path('../certs/key.pem', __FILE__),\n  ssl_cert: File.expand_path('../certs/cert.pem', __FILE__)\n}\nserver = Noder::HTTP::Server.new(options)\n```\n\nNotes\n-----\n\nNoder is not currently a full implementation of Node.js, and some of its underlying architecture differs from Node.js's. If you see any places where it could be improved or added to, absolutely feel free to submit a PR.\n\nLicense\n-------\n\nNoder is released under the MIT License. Please see the MIT-LICENSE file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftombenner%2Fnoder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftombenner%2Fnoder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftombenner%2Fnoder/lists"}