diff --git a/Gemfile b/Gemfile
index 4753856..88ece7d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -23,6 +23,10 @@ gem 'eita-jrails', '~> 0.9.5', require: 'jrails'
# API dependencies
gem 'grape', '~> 0.12'
gem 'grape-entity'
+gem 'grape-swagger'
+gem 'swagger-ui_rails'
+gem 'kramdown'
+
#FIXME Get the Grape Loggin from master yo solve this issue https://github.com/intridea/grape/issues/1059
#We have to remove this commit referenve code when update the next release of grape_logging. Actualy we are using (1.1.2)
gem 'grape_logging', :git => 'https://github.com/aceunreal/grape_logging.git', :ref => 'f1755ae'
diff --git a/app/controllers/api_docs_controller.rb b/app/controllers/api_docs_controller.rb
new file mode 100644
index 0000000..3464314
--- /dev/null
+++ b/app/controllers/api_docs_controller.rb
@@ -0,0 +1,8 @@
+class ApiDocsController < ApplicationController
+ layout :api_layout
+
+ private
+ def api_layout
+ params[:controller]
+ end
+end
diff --git a/app/views/api_docs/index.html.erb b/app/views/api_docs/index.html.erb
new file mode 100644
index 0000000..9e67f55
--- /dev/null
+++ b/app/views/api_docs/index.html.erb
@@ -0,0 +1 @@
+<%= render 'swagger_ui/swagger_ui', discovery_url: '/api/v1/api_docs' %>
diff --git a/app/views/layouts/api_docs.html.erb b/app/views/layouts/api_docs.html.erb
new file mode 100644
index 0000000..d594591
--- /dev/null
+++ b/app/views/layouts/api_docs.html.erb
@@ -0,0 +1,14 @@
+
+
+
+
+
+ <%= stylesheet_link_tag 'swagger-ui' %>
+ <%= javascript_include_tag 'swagger-ui' %>
+
+
+
+ <%= yield %>
+
+
+
diff --git a/config/routes.rb b/config/routes.rb
index 1aae0d4..c329f43 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -23,6 +23,7 @@ Noosfero::Application.routes.draw do
match 'site(/:action)', :controller => 'home'
match 'api(/:action)', :controller => 'api'
+ match 'api_docs(/:action)', :controller => 'api_docs'
match 'images(/*stuff)' => 'not_found#nothing'
match 'stylesheets(/*stuff)' => 'not_found#nothing'
diff --git a/lib/noosfero/api/api.rb b/lib/noosfero/api/api.rb
index 2d0cdd3..5f01a17 100644
--- a/lib/noosfero/api/api.rb
+++ b/lib/noosfero/api/api.rb
@@ -52,6 +52,8 @@ module Noosfero
mount Session
+ add_swagger_documentation api_version: 'v1', mount_path: '/api_docs', markdown: GrapeSwagger::Markdown::KramdownAdapter unless Rails.env.production?
+
# hook point which allow plugins to add Grape::API extensions to API::API
#finds for plugins which has api mount points classes defined (the class should extends Grape::API)
@plugins = Noosfero::Plugin.all.map { |p| p.constantize }
diff --git a/lib/noosfero/api/entities.rb b/lib/noosfero/api/entities.rb
index 5f8636f..4b0cbf6 100644
--- a/lib/noosfero/api/entities.rb
+++ b/lib/noosfero/api/entities.rb
@@ -43,7 +43,7 @@ module Noosfero
class Person < Profile
root 'people', 'person'
- expose :user, :using => UserBasic
+ expose :user, :using => UserBasic, documentation: {type: 'User', desc: 'The user data of a person' }
end
class Enterprise < Profile
@@ -74,11 +74,11 @@ module Noosfero
root 'articles', 'article'
expose :id
expose :body
- expose :abstract
+ expose :abstract, documentation: {type: 'String', desc: 'Teaser of the body'}
expose :created_at, :format_with => :timestamp
expose :title, :documentation => {:type => "String", :desc => "Title of the article"}
- expose :created_by, :as => :author, :using => Profile
- expose :profile, :using => Profile
+ expose :created_by, :as => :author, :using => Profile, :documentation => {type: 'Profile', desc: 'The profile author that create the article'}
+ expose :profile, :using => Profile, :documentation => {type: 'Profile', desc: 'The profile associated with the article'}
expose :categories, :using => Category
expose :image, :using => Image
#TODO Apply vote stuff in core and make this test
@@ -88,7 +88,7 @@ module Noosfero
expose :position
expose :hits
expose :start_date
- expose :end_date
+ expose :end_date, :documentation => {type: 'DateTime', desc: 'The date of finish of the article'}
expose :tag_list
end
@@ -98,6 +98,7 @@ module Noosfero
expose :children, using: ArticleBase do |article, options|
article.children.limit(Noosfero::API::V1::Articles::MAX_PER_PAGE)
end
+ expose :slug, :documentation => {:type => "String", :desc => "Trimmed and parsed name of a article"}
end
class Comment < Entity
@@ -127,7 +128,7 @@ module Noosfero
end
class UserLogin < User
- expose :private_token
+ expose :private_token, documentation: {type: 'String', desc: 'A valid authentication code for post/delete api actions'}
end
class Task < Entity
diff --git a/lib/noosfero/api/v1/articles.rb b/lib/noosfero/api/v1/articles.rb
index 5ef335f..30f1519 100644
--- a/lib/noosfero/api/v1/articles.rb
+++ b/lib/noosfero/api/v1/articles.rb
@@ -21,15 +21,40 @@ module Noosfero
# Example Request:
# GET host/api/v1/articles?from=2013-04-04-14:41:43&until=2015-04-04-14:41:43&limit=10&private_token=e96fff37c2238fdab074d1dcea8e6317
+ desc 'Return all articles of all kinds' do
+ detail 'Get all articles filtered by fields in query params'
+ params Noosfero::API::Entities::Article.documentation
+ success Noosfero::API::Entities::Article
+ failure [[403, 'Forbidden']]
+ named 'ArticlesList'
+ headers [
+ 'Per-Page' => {
+ description: 'Total number of records',
+ required: false
+ }
+ ]
+ end
get do
present_articles(environment)
end
- desc "Return the article id"
+ desc "Return one article by id" do
+ detail 'Get only one article by id. If not found the "forbidden" http error is showed'
+ params Noosfero::API::Entities::Article.documentation
+ success Noosfero::API::Entities::Article
+ failure [[403, 'Forbidden']]
+ named 'ArticleById'
+ end
get ':id', requirements: {id: /[0-9]+/} do
present_article(environment)
end
-
+
+ desc 'Report a abuse and/or violent content in a article by id' do
+ detail 'Submit a abuse (in general, a content violation) report about a specific article'
+ params Noosfero::API::Entities::Article.documentation
+ failure [[400, 'Bad Request']]
+ named 'ArticleReportAbuse'
+ end
post ':id/report_abuse' do
article = find_article(environment.articles, params[:id])
profile = article.profile
@@ -58,14 +83,23 @@ module Noosfero
end
- desc "Returns the total followers for the article"
+ desc "Returns the total followers for the article" do
+ detail 'Get the followers of a specific article by id'
+ failure [[403, 'Forbidden']]
+ named 'ArticleFollowers'
+ end
get ':id/followers' do
article = find_article(environment.articles, params[:id])
total = article.person_followers.count
{:total_followers => total}
end
- desc "Add a follower for the article"
+ desc "Add a follower for the article" do
+ detail 'Add the current user identified by private token, like a follower of a article'
+ params Noosfero::API::Entities::UserLogin.documentation
+ failure [[401, 'Unauthorized']]
+ named 'ArticleFollow'
+ end
post ':id/follow' do
authenticate!
article = find_article(environment.articles, params[:id])
@@ -80,6 +114,12 @@ module Noosfero
end
end
+ desc 'Perform a vote on a article by id' do
+ detail 'Vote on a specific article with values: 1 (if you like) or -1 (if not)'
+ params Noosfero::API::Entities::UserLogin.documentation
+ failure [[401,'Unauthorized']]
+ named 'ArticleVote'
+ end
post ':id/vote' do
authenticate!
value = (params[:value] || 1).to_i
@@ -90,6 +130,12 @@ module Noosfero
{:vote => vote.save}
end
+ desc 'Return the children of a article identified by id' do
+ detail 'Get all children articles of a specific article'
+ params Noosfero::API::Entities::Article.documentation
+ failure [[403, 'Forbidden']]
+ named 'ArticleChildren'
+ end
get ':id/children' do
article = find_article(environment.articles, params[:id])
@@ -108,6 +154,13 @@ module Noosfero
present articles, :with => Entities::Article, :fields => params[:fields]
end
+ desc 'Return one child of a article identified by id' do
+ detail 'Get a child of a specific article'
+ params Noosfero::API::Entities::Article.documentation
+ success Noosfero::API::Entities::Article
+ failure [[403, 'Forbidden']]
+ named 'ArticleChild'
+ end
get ':id/children/:child_id' do
article = find_article(environment.articles, params[:id])
child = find_article(article.children, params[:child_id])
@@ -115,6 +168,13 @@ module Noosfero
present child, :with => Entities::Article, :fields => params[:fields]
end
+ desc 'Suggest a article to another profile' do
+ detail 'Suggest a article to another profile (person, community...)'
+ params Noosfero::API::Entities::Article.documentation
+ success Noosfero::API::Entities::Task
+ failure [[401,'Unauthorized']]
+ named 'ArticleSuggest'
+ end
post ':id/children/suggest' do
authenticate!
parent_article = environment.articles.find(params[:id])
@@ -133,6 +193,13 @@ module Noosfero
# Example Request:
# POST api/v1/articles/:id/children?private_token=234298743290432&article[name]=title&article[body]=body
+ desc 'Add a child article to a parent identified by id' do
+ detail 'Create a new article and associate to a parent'
+ params Noosfero::API::Entities::Article.documentation
+ success Noosfero::API::Entities::Article
+ failure [[401,'Unauthorized']]
+ named 'ArticleAddChild'
+ end
post ':id/children' do
authenticate!
parent_article = environment.articles.find(params[:id])
@@ -162,6 +229,14 @@ module Noosfero
resource kind.pluralize.to_sym do
segment "/:#{kind}_id" do
resource :articles do
+
+ desc "Return all articles associate with a profile of type #{kind}" do
+ detail 'Get a list of articles of a profile'
+ params Noosfero::API::Entities::Article.documentation
+ success Noosfero::API::Entities::Article
+ failure [[403, 'Forbidden']]
+ named 'ArticlesOfProfile'
+ end
get do
profile = environment.send(kind.pluralize).find(params["#{kind}_id"])
@@ -178,6 +253,13 @@ module Noosfero
end
end
+ desc "Return a article associate with a profile of type #{kind}" do
+ detail 'Get only one article of a profile'
+ params Noosfero::API::Entities::Article.documentation
+ success Noosfero::API::Entities::Article
+ failure [[403, 'Forbidden']]
+ named 'ArticleOfProfile'
+ end
get ':id' do
profile = environment.send(kind.pluralize).find(params["#{kind}_id"])
present_article(profile)
@@ -185,6 +267,13 @@ module Noosfero
# Example Request:
# POST api/v1/{people,communities,enterprises}/:asset_id/articles?private_token=234298743290432&article[name]=title&article[body]=body
+ desc "Add a new article associated with a profile of type #{kind}" do
+ detail 'Create a new article and associate with a profile'
+ params Noosfero::API::Entities::Article.documentation
+ success Noosfero::API::Entities::Article
+ failure [[403, 'Forbidden']]
+ named 'ArticleCreateToProfile'
+ end
post do
profile = environment.send(kind.pluralize).find(params["#{kind}_id"])
post_article(profile, params)
--
libgit2 0.21.2