{"id":28578162,"url":"https://github.com/digitalocean/resource_kit","last_synced_at":"2025-06-11T01:09:03.383Z","repository":{"id":19373397,"uuid":"22613761","full_name":"digitalocean/resource_kit","owner":"digitalocean","description":"Resource Kit provides tools to aid in making API Clients. Such as URL resolving, Request / Response layer, and more.","archived":false,"fork":false,"pushed_at":"2023-07-06T19:59:23.000Z","size":99,"stargazers_count":140,"open_issues_count":11,"forks_count":64,"subscribers_count":142,"default_branch":"main","last_synced_at":"2025-06-09T11:45:57.725Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://github.com/digitaloceancloud/resource_kit","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/digitalocean.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-08-04T17:44:51.000Z","updated_at":"2025-05-01T09:35:36.000Z","dependencies_parsed_at":"2024-06-18T14:08:05.317Z","dependency_job_id":null,"html_url":"https://github.com/digitalocean/resource_kit","commit_stats":null,"previous_names":["digitaloceancloud/resource_kit"],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fresource_kit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fresource_kit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fresource_kit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fresource_kit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/digitalocean","download_url":"https://codeload.github.com/digitalocean/resource_kit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fresource_kit/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259178519,"owners_count":22817388,"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","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":[],"created_at":"2025-06-11T01:09:02.492Z","updated_at":"2025-06-11T01:09:03.340Z","avatar_url":"https://github.com/digitalocean.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Resource Kit\n\nResource Kit provides tools to aid in making API Clients. Such as URL resolving, Request / Response layer, and more.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n    gem 'resource_kit'\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install resource_kit\n\n## Usage\n\nThis library recommends using [Kartograph](http://github.com/digitaloceancloud/kartograph) for representing and deserializing response bodies.\nYou'll see it in the examples provided below.\n\n### Resource classes\n\nResource Kit provides a comprehensive but intuitive DSL where you describe the remote resources capabilities.\nFor example, where can I get a list of users? Where do I get a single user? How do I create a user?\n\nWhen you're able to answer these questions, you can describe them in your resource class like this:\n\n```ruby\nclass DropletResource \u003c ResourceKit::Resource\n  resources do\n    default_handler(422) { |response| ErrorMapping.extract_single(response.body, :read) }\n    default_handler(:ok, :created) { |response| DropletMapping.extract_single(response.body, :read) }\n    default_handler { |response| raise \"Unexpected response status #{response.status}... #{response.body}\" }\n\n    # Defining actions will create instance methods on the resource class to call them.\n    action :find do\n      verb :get # get is assumed if this is omitted\n      path '/droplets/:id'\n      handler(200) { |response| DropletMapping.extract_single(response.body, :read) }\n    end\n\n    action :all do\n      path '/droplets'\n      handler(200) { |body| DropletMapping.extract_collection(body, :read) }\n    end\n\n    action :create do\n      path '/droplets'\n      verb :post\n      body { |object| DropletMapping.representation_for(:create, object) } # Generate a response body from a passed object\n      handler(202) { |response| DropletMapping.extract_single(response.body, :read) }\n    end\n  end\nend\n```\n\nYou also have the option to use a shorter version to describe actions like this:\n\n```ruby\nclass DropletResource \u003c ResourceKit::Resource\n  resources do\n    action :all, 'GET /v2/droplets' do\n      handler(:ok) { |response| DropletMapping.extract_collection(response.body, :read) }\n    end\n  end\nend\n```\n\nInstead of using `#action`, you can use any of the supported HTTP verb methods including `#get`, `#post`, `#put`, `#delete`, `#head`, `#patch`, and `#options`. Thus, the above example can be also written as:\n\n```ruby\nclass DropletResource \u003c ResourceKit::Resource\n  resources do\n    get :all, '/v2/droplets' do\n      handler(:ok) { |response| DropletMapping.extract_collection(response.body, :read) }\n    end\n  end\nend\n```\n\nNow that we've described our resources. We can instantiate our class with a connection object. ResourceKit relies on the interface that Faraday provides. For example:\n\n```ruby\nconn = Faraday.new(url: 'http://api.digitalocean.com') do |req|\n  req.adapter :net_http\nend\n\nresource = DropletResource.new(connection: conn)\n```\n\nNow that we've instantiated a resource with our class, we can call the actions we've defined on it.\n\n```\nall_droplets = resource.all\nsingle_droplet = resource.find(id: 123)\ncreate = resource.create(Droplet.new)\n```\n\n## Scope\n\nResourceKit classes give you the option to pass in an optional scope object, so that you may interact with the resource with it that way.\n\nFor example, you may want to use this for nested resources:\n\n```ruby\nclass CommentResource \u003c ResourceKit::Resource\n  resources do\n    action :all do\n      path { \"/users/#{user_id}/comments\" }\n      handler(200) { |resp| CommentMapping.extract_collection(resp.body, :read) }\n    end\n  end\n\n  def user_id\n    scope.user_id\n  end\nend\n\nuser = User.find(123)\nresource = CommentResource.new(connection: conn, scope: user)\ncomments = resource.all #=\u003e Will fetch from /users/123/comments\n```\n\n## Test Helpers\n\nResourceKit supplys test helpers that assist in certain things you'd want your resource classes to do.\n\nMake sure you:\n\n    require 'resource_kit/testing'\n\nTesting a certain action:\n\n```ruby\n# Tag the spec with resource_kit to bring in the helpers\nRSpec.describe MyResourceClass, resource_kit: true do\n  it 'has an all action' do\n    expect(MyResourceClass).to have_action(:all).that_handles(:ok, :no_content).at_path('/users')\n  end\n\n  it 'handles a 201 with response body' do\n    expect(MyResourceClass).to handle_response(:create).with(status: 201, body: '{\"users\":[]}') do |handled|\n      expect(handled).to all(be_kind_of(User))\n    end\n  end\nend\n```\n\n### Nice to have's\n\nThings we've thought about but just haven't implemented are:\n\n* Pagination capabilities\n\n\n## Contributing\n\n1. Fork it ( https://github.com/digitaloceancloud/resource_kit/fork )\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Releasing\n\n1. Update the [version](./lib/resource_kit/version.rb) \n2. Commit the version and push it to master\n3. Run `rake release`\n\nNote: In order to run `rake release` you must be authenticated w/ rubygems.org.  To do this, you need to locate the rubygems account information contained within DOs lastpass account (search for rubygems).\nOnce you have done this, do the following:\n1. `gem push`\n2. Follow the prompts and add the required information\n3. Run `rake release`\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalocean%2Fresource_kit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdigitalocean%2Fresource_kit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalocean%2Fresource_kit/lists"}