Skip to main content

Controllers

Overview

Controllers live under app/controllers/decidim/api/rest_full/. They authorize, call operations or serializers, and render JSON. No business logic in the controller.

When to use

  • You add a new HTTP surface for a feature gem.
  • You wire async, sync, or conditional GET behaviour.

Example

1. Subclass the right base controller

Participatory resource: decidim-restfull-blogs/app/controllers/decidim/api/rest_full/blogs/blogs_controller.rb

class BlogsController < Decidim::Api::RestFull::Core::ResourcesController

Org-scoped (no component): decidim-restfull-core/app/controllers/decidim/api/rest_full/roles/roles_controller.rb

class RolesController < Decidim::Api::RestFull::ApplicationController

2. Authorize scope and permission

before_action { doorkeeper_authorize! :blogs }
before_action { ability.authorize! :read, ::Decidim::Blogs::Post }

3. Render GETs with conditional cache

def show
@resource = find_resource!
render_json_with_conditional_get(
serialized_show(@resource),
fingerprint: resource_fingerprint_for(@resource)
)
end

See HTTP cache.

4. Enqueue mutations (and add *_sync when needed)

include Decidim::Api::RestFull::AsyncApiJobEnqueuing

def create
enqueue_rest_full_api_job!("widgets#create")
end

See Async.

5. Register routes in the engine

decidim-restfull-widgets/lib/decidim/rest_full/widgets/engine.rbext.routes block. See Routing.

6. Add an RSwag request spec

decidim-restfull-widgets/spec/requests/decidim/api/rest_full/widgets/widgets_controller_show_spec.rb

Register the glob:

ext.rswag_specs File.join(Widgets::ENGINE_ROOT, "spec/requests/decidim/api/rest_full/widgets/**/*_spec.rb")

Participatory specs need let(:component_id), let(:space_id), let(:space_manifest).

Rules

RuleDetail
Thin controllersDelegate to *Operations or serializers.
api_context / api_execution_contextPass to operations from sync actions and jobs.
Organization scopeUsers, roles: current_organization; not ResourcesController#filter_for_context.
Component scopeResources: component_id, space_id, space_manifest query params.
ErrorsRaised as ApiException; handled in ApplicationController.
PatternPath
Component resourcedecidim-restfull-blogs/spec/requests/.../blogs_controller_show_spec.rb
Async + syncdecidim-restfull-proposals/spec/requests/.../draft_proposals_controller_create_spec.rb
Org-scopeddecidim-restfull-core/spec/requests/.../roles/roles_controller_index_spec.rb

Use describe_api_endpoint for OpenAPI security metadata.

See also