{"id":27118599,"url":"https://github.com/doga/jsonapi_for_rails","last_synced_at":"2025-04-07T07:58:58.869Z","repository":{"id":56879475,"uuid":"52171693","full_name":"doga/jsonapi_for_rails","owner":"doga","description":"A Rails plugin for providing JSON API compliant APIs with very little coding. http://jsonapi.org/format/ http://rubyonrails.org/","archived":false,"fork":false,"pushed_at":"2017-10-18T13:48:14.000Z","size":101,"stargazers_count":19,"open_issues_count":1,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-23T02:33:23.607Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/doga.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":"2016-02-20T19:36:59.000Z","updated_at":"2024-08-31T02:17:26.000Z","dependencies_parsed_at":"2022-08-20T23:10:56.051Z","dependency_job_id":null,"html_url":"https://github.com/doga/jsonapi_for_rails","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doga%2Fjsonapi_for_rails","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doga%2Fjsonapi_for_rails/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doga%2Fjsonapi_for_rails/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doga%2Fjsonapi_for_rails/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/doga","download_url":"https://codeload.github.com/doga/jsonapi_for_rails/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247615460,"owners_count":20967183,"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-04-07T07:58:58.236Z","updated_at":"2025-04-07T07:58:58.862Z","avatar_url":"https://github.com/doga.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JsonapiForRails\nA [Rails](http://rubyonrails.org/) 4+ plugin for providing [JSONAPI v1.0](http://jsonapi.org/format/1.0/) compliant APIs from your application with very little coding.\n\n* [Installation](#installation)\n* [Usage](#usage)\n  1. [Set up one API controller per model](#1-set-up-one-api-controller-per-model)\n  2. [Configure your API controller routes](#2-configure-your-api-controller-routes)\n  3. [Verify your setup](#3-verify-your-setup)\n* [Modifying the default API behaviour](#modifying-the-default-api-behaviour)\n  * [Client authentication](#client-authentication)\n  * [Access control](#access-control)\n  * [Overriding an API end-point](#overriding-an-api-end-point)\n* [Implementation status](#implementation-status)\n* [Contributing](#contributing)\n* [License](#license)\n\n## Installation\n\n```bash\n$ # Optional security step (do this once)\n$ gem cert --add \u003c(curl -Ls https://raw.githubusercontent.com/doga/jsonapi_for_rails/master/certs/doga.pem)\n$\n$ # Go to the root directory of your existing Rails application\n$ cd path/to/railsapp\n$\n$ # Update the gem file\n$ echo \"gem 'jsonapi_for_rails'\" \u003e\u003e Gemfile\n$\n$ # Install\n$ # (Optional security paramater: --trust-policy MediumSecurity)\n$ bundle install --trust-policy MediumSecurity\n$\n$ # Check the used version\n$ bin/rails console\nirb(main):001:0\u003e JsonapiForRails::VERSION\n=\u003e \"0.2.1\"\nirb(main):002:0\u003e exit\n$\n```\n\n## Usage\n\n### 1. Set up one API controller per model\n\nGenerate a controller for each model that will be accessible from your API. Controller names need to be the plural version of your model names.\n\n```bash\n$ cd path/to/railsapp\n$\n$ # Generate your models\n$ bin/rails generate model article\n$ bin/rails generate model author\n$\n$ # Generate your API controllers\n$ bin/rails generate controller articles\n$ bin/rails generate controller authors\n```\n\nThen enable JSONAPI in a parent class of your API controllers. \n\n```ruby\n# app/controllers/application_controller.rb\nclass ApplicationController \u003c ActionController::Base # or ActionController::API\n\n  # Enable JSONAPI\n  acts_as_jsonapi_resources(\n    # links:               false,\n    # content_negotiation: false\n  )\n\n  # ...\nend\n```\n\n`acts_as_jsonapi_resources` accepts the following keyword arguments:\n\n* `links`: Setting this to `false` disables\n  [link generation](http://jsonapi.org/format/1.0/#document-links),\n  and speeds up your API. The default value is `true`.\n* `content_negotiation`: Setting this to `false` disables\n  [content negotiation](http://jsonapi.org/format/1.0/#content-negotiation). Again, this helps speed up your API, but at the expense of making your API non-JSONAPI-compliant, if only just). The default value is `true`. \n\nIf only some of your controllers are JSONAPI controllers, then create a parent controller for only those controllers, and enable JSONAPI inside that controller rather than `ApplicationController`. \n\n```bash\n$ cat \u003e app/controllers/jsonapi_resources_controller.rb\n\nclass JsonapiResourcesController \u003c ApplicationController\n  acts_as_jsonapi_resources\n\n  # ...\nend\n```\n\n```ruby\n# app/controllers/articles_controller.rb\n\n# Change the API controller's parent class\nclass ArticlesController \u003c JsonapiResourcesController\n  # ...\nend\n\n# Do the same with AuthorsController\n```\n\n### 2. Configure your API controller routes\nUpdate your application routes as follows:\n\n```ruby\n# config/routes.rb\nRails.application.routes.draw do\n  # ...\n\n  scope '/api/v1' do # Optional scoping\n\n    [ # List your API controllers here\n      :articles, :authors\n    ].each do |resources_name|\n      resources resources_name do\n        controller resources_name do\n          get     'relationships/:relationship', action: \"relationship_show\"\n          patch   'relationships/:relationship', action: \"relationship_update\"\n          post    'relationships/:relationship', action: \"relationship_add\"\n          delete  'relationships/:relationship', action: \"relationship_remove\"\n        end\n      end\n    end\n\n  end\n\n  # ...\nend\n\n```\n\n### 3. Verify your setup\nAfter populating your database and launching the built-in Rails server with the `bin/rails server` shell command, you can issue some HTTP requests to your API and verify the correctness of the responses.\n\n```bash\n$ # Get the list of articles\n$ # (the returned HTTP response body is short and terse, but is prettified here for legibility)\n$ curl 'http://localhost:3000/api/v1/articles'\n{\n  \"data\": [\n    {\n      \"type\": \"articles\",\n      \"id\": \"618037523\"\n    },\n    {\n      \"type\": \"articles\",\n      \"id\": \"994552601\"\n    }\n  ],\n  \"links\": {\n    \"self\": \"/api/v1/articles\"\n  }\n}\n$ # Get an article\n$ curl 'http://localhost:3000/api/v1/articles/618037523'\n{\n  \"data\": {\n    \"type\": \"articles\",\n    \"id\": \"618037523\",\n    \"attributes\": {\n      \"title\": \"UK bank pay and bonuses in the spotlight as results season starts\",\n      \"content\": \"The pay deals handed to the bosses of Britain’s biggest banks ...\",\n      \"created_at\": \"2016-03-02 14:33:49 UTC\",\n      \"updated_at\": \"2016-03-02 14:33:49 UTC\"\n    },\n    \"relationships\": {\n      \"author\": {\n        \"data\": {\n          \"type\": \"authors\",\n          \"id\": \"1023487079\"\n        }\n      }\n    },\n    \"links\": {\n      \"self\": \"/api/v1/articles/618037523\"\n    }\n  }\n}\n$ # Get only the title and author of an article, include the author's name\n$ curl 'http://localhost:3000/api/v1/articles/618037523?filter%5Barticles%5D=title,author;include=author;filter%5Bauthors%5D=name'\n{\n  \"data\": {\n    \"type\": \"articles\",\n    \"id\": \"618037523\",\n    \"attributes\": {\n      \"title\": \"UK bank pay and bonuses in the spotlight as results season starts\"\n    },\n    \"relationships\": {\n      \"author\": {\n        \"data\": {\n          \"type\": \"authors\",\n          \"id\": \"1023487079\"\n        }\n      }\n    },\n    \"links\": {\n      \"self\": \"/api/v1/articles/618037523\"\n    }\n  },\n  \"include\": [\n    {\n      \"data\": {\n        \"type\": \"authors\",\n        \"id\": \"1023487079\",\n        \"attributes\": {\n          \"name\": \"Jill T...\"\n        },\n        \"relationships\": {\n        },\n        \"links\": {\n          \"self\": \"/api/v1/authors/1023487079\"\n        }\n      }\n    }\n  ]\n}\n$\n```\n\n## Modifying the default API behaviour\nBy default, all API end-points are accessible to all clients, and all end-points behave the same way for all clients. In a real-world setting, you may want to restrict access to an end-point and/or change the behaviour of an end-point depending on the client. \n\n### Client authentication\nClients can be authenticated with a `before_action` method in your API controller. Inside controllers, instance variable names starting with the `@jsonapi_` prefix and method names starting with the `jsonapi_` prefix are reserved by *jsonapi_for_rails*, so try to avoid those.\n\n```ruby\n# app/controllers/jsonapi_resources_controller.rb\nclass JsonapiResourcesController \u003c ApplicationController\n  acts_as_jsonapi_resources\n\n  before_action :authenticate\n\nprivate\n  def authenticate\n    # ...\n  end\nend\n```\n\n### Access control\nAccess control for authenticated and unauthenticated clients can be implemented in `before_action` methods in your API controllers.\n\n```ruby\n# app/controllers/jsonapi_resources_controller.rb\nclass JsonapiResourcesController \u003c ApplicationController\n  acts_as_jsonapi_resources\n\n  before_action :permit_read, only: [\n    :index,\n    :show,\n    :relationship_show\n  ]\n\n  before_action :permit_write, only: [\n    :create, \n    :update, \n    :destroy,\n    :relationship_update,\n    :relationship_add,\n    :relationship_remove\n  ]\n\nprivate\n  def permit_read\n    # ...\n  end\n\n  def permit_write\n    # ...\n  end\nend\n```\n\n### Overriding an API end-point\nThe `bin/rails routes` shell command shows you the end-points that *jsonapi_for_rails* defines. In order to change the behaviour of an action, you can define an action with the same name inside an API controller. *jsonapi_for_rails* provides utility methods and instance variables that can help you.\n\n```ruby\n# app/controllers/articles_controller.rb\nclass ArticlesController \u003c JsonapiResourcesController \n\n  def index\n    # These model-related utility methods are available inside all action methods.\n    jsonapi_model_class # =\u003e  Article\n    jsonapi_model_type  # =\u003e :articles\n\n    # @jsonapi_links indicates whether links should be included in response documents.\n    # It is available inside all action methods.\n    @jsonapi_links      # =\u003e true\n\n    # ...\n  end\n\n  def show\n    # @jsonapi_record contains the current database record.\n    # It is available inside all action methods (including all relationship\n    # methods) except :index and :create.\n    @jsonapi_record.to_jsonapi_hash        # =\u003e {data:   {...}}\n    @jsonapi_record.to_jsonapi_errors_hash # =\u003e {errors: [...]}\n\n    # ...\n  end\n\n  def relationship_show\n    # @jsonapi_relationship is available in all relationship action methods.\n    # @jsonapi_relationship[:definition] describes the current relationship.\n    @jsonapi_relationship # =\u003e {:definition=\u003e{:name=\u003e:author, :type=\u003e:to_one, :receiver=\u003e{:type=\u003e:authors, :class=\u003eAuthor}}}\n\n    # ...\n  end\n\n  def relationship_update\n    # @jsonapi_relationship[:params] contains the parsed request body.\n    # It is available for all relationship action methods except relationship_show.\n    # @jsonapi_relationship[:params][:data] behaves like a Hash for relationships\n    # of type :to_one, and as an Array for relationships of type :to_many.\n    @jsonapi_relationship # =\u003e {:definition=\u003e{...}, :params=\u003e{\"data\"=\u003e{\"type\"=\u003e\"authors\", \"id\"=\u003e\"234455384\"}}}\n\n    # ...\n  end\n\nend\n```\n\n## Implementation status\nThe internal architecture is sound. Test coverage is currently being bulked up using *Rails 5 beta 2* (but the plugin should be compatible with *Rails 4+*). And missing features are being added. The intention is to release a 1.0 version around mid-2016.\n\nFeature support roundup:\n\n* [Content negotiation](http://jsonapi.org/format/1.0/#content-negotiation) is implemented and enabled by default, but can be disabled.\n* [Link generation](http://jsonapi.org/format/1.0/#document-links) is implemented and enabled by default, but can be disabled.\n* [Inclusion of related resources](http://jsonapi.org/format/1.0/#fetching-includes) is currently only implemented for requests that return a single resource, and relationship paths are not supported. \n* [Sparse fieldsets](http://jsonapi.org/format/1.0/#fetching-sparse-fieldsets) is currently only implemented for requests that return a single resource. \n* [Sorting](http://jsonapi.org/format/1.0/#fetching-sorting) is currently not implemented.\n* [Pagination](http://jsonapi.org/format/1.0/#fetching-pagination) is currently not implemented.\n* [Deleting resources](http://jsonapi.org/format/1.0/#crud-deleting) is currently not implemented.\n\n## Contributing\nFeel free to share your experience using this software. If you find a bug in this project, have trouble following the documentation or have a question about the project – create an [issue](https://github.com/doga/jsonapi_for_rails/issues).\n\n## License\nThe gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoga%2Fjsonapi_for_rails","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdoga%2Fjsonapi_for_rails","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoga%2Fjsonapi_for_rails/lists"}