DocumentationAPI
grep -rn --color --exclude-dir 'config/locales' --exclude-dir 'vendor' --exclude-dir 'public' --exclude-dir 'log' 'api' .
SETTINGS
./config/settings.yml:91:sys_api_enabled:
./config/settings.yml:93:sys_api_key:
./config/settings.yml:131:mail_handler_api_enabled:
./config/settings.yml:133:mail_handler_api_key:
./config/settings.yml:193:rest_api_enabled:
THE WORKFLOW
-
> Mime Type 'api' registered
-
> respond_to.api
-
> Template Handler 'api' registered
-
> Builder.for(params[:format])
Supported Formats
The global api - methods
./config/initializers/10-patches.rb:99: def api(&block)
# registers the mime type for api
module ActionController
module MimeResponds
class Responder
def api(&block)
any(:xml, :json, &block)
end
end
end
end
./app/helpers/application_helper.rb:922: def api_meta(options)
Including Relations
./app/helpers/application_helper.rb:911: def include_in_api_response?(arg)
# Returns true if arg is expected in the API response
def include_in_api_response?(arg)
unless @included_in_api_response
param = params[:include]
@included_in_api_response = param.is_a?(Array) ? param.collect(&:to_s) : param.to_s.split(',')
@included_in_api_response.collect!(&:strip)
end
@included_in_api_response.include?(arg.to_s)
end
Where is it
./app/views/issues/show.api.rsb: render_api_issue_children(@issue, api) if include_in_api_response?('children')
./app/views/issues/show.api.rsb: end if include_in_api_response?('relations') && @relations.present?
./app/views/issues/show.api.rsb: end if include_in_api_response?('changesets') && User.current.allowed_to?(:view_changesets, @project)
./app/views/issues/show.api.rsb: end if include_in_api_response?('journals')
./app/views/projects/show.api.rsb: end if include_in_api_response?('trackers')
./app/views/users/show.api.rsb: end if include_in_api_response?('memberships') && @memberships
Building the Response
/lib/redmine/views/api_template_handler.rb:24
def compile(template)
"Redmine::Views::Builders.for(params[:format]) do |api|; #{template.source}; self.output_buffer = api.output; end"
end
The authentication system
User
/app/models/user.rb:52: has_one :api_token, :dependent => :destroy, :class_name => 'Token', :conditions => "action='api'"
has_one :rss_token, :dependent => :destroy, :class_name => 'Token', :conditions => "action='feeds'"
has_one :api_token, :dependent => :destroy, :class_name => 'Token', :conditions => "action='api'"
./app/models/user.rb:246: def api_key
./app/models/user.rb:247: token = self.api_token || self.create_api_token(:action => 'api')
def api_key
token = self.api_token || self.create_api_token(:action => 'api')
token.value
end
./app/models/user.rb:294: def self.find_by_api_key(key)
def self.find_by_api_key(key)
token = Token.find_by_action_and_value('api', key)
token && token.user.active? ? token.user : nil
end
API enabled controllers (06/16/2011)
/timelog_controller.rb
/projects_controller.rb
/news_controller.rb
/issues_controller.rb
/users_controller.rb
# IssuesController#index
respond_to do |format|
format.html { render :template => 'issues/index.rhtml', :layout => !request.xhr? }
# HERE
format.api
format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") }
format.csv { send_data(issues_to_csv(@issues, @project), :type => 'text/csv; header=present', :filename => 'export.csv') }
format.pdf { send_data(issues_to_pdf(@issues, @project, @query), :type => 'application/pdf', :filename => 'export.pdf') }
end
Builder Templates
./app/views/issues/index.api.rsb
api.array :issues, api_meta(:total_count => @issue_count, :offset => @offset, :limit => @limit) do
@issues.each do |issue|
api.issue do
api.id issue.id
api.project(:id => issue.project_id, :name => issue.project.name) unless issue.project.nil?
api.tracker(:id => issue.tracker_id, :name => issue.tracker.name) unless issue.tracker.nil?
api.done_ratio issue.done_ratio
api.estimated_hours issue.estimated_hours
render_api_custom_values issue.custom_field_values, api
api.created_on issue.created_on
api.updated_on issue.updated_on
end
end
end
./app/helpers/custom_fields_helper.rb:109: def render_api_custom_values(custom_values, api)
# Renders the custom_values in api views
def render_api_custom_values(custom_values, api)
api.array :custom_fields do
custom_values.each do |custom_value|
api.custom_field :id => custom_value.custom_field_id, :name => custom_value.custom_field.name do
api.value custom_value.value
end
end
end unless custom_values.empty?
end