3.0 REST API
From AlfrescoWiki
This page represents on-going design of the 3.0 Repository Public RESTful API for use by any client. As each service is implemented and formally described it becomes self-documenting allowing for the generation of the published reference documentation (which will also be available from an installed Alfresco Repository).
The scope of services is heavily driven by the requirements of the Alfresco 3.0 Web Client.
Alfresco REST Design Guidelines
Contents |
[edit] Node Service (TBD)
[edit] Data
[edit] Node
{
"nodeRef" : "workspace://SpacesStore/123-123-123",
"url" : "/services/api/node/workspace/SpacesStore/123-123-123"
}
[edit] Site Service
[edit] Data
[edit] Site Details
Details of the site that include:
- short name (this must be unique and always present)
- site preset (mandatory for create)
- title
- description
- indication of whether the site is public
- site node URL
- tag scope URL for the site
- site URL (provided when retrieving site details)
JSON example:
{
"shortName" : "shortName",
"sitePreset" : "sitePresetName",
"title" : "title",
"description" : "description",
"isPublic" : true,
"node" : "/services/api/node/workspace/SpacesStore/123-123-123-123",
"tagScope" : "/services/api/tagscopes/workspace/SpacesStore/123-123-123-123"
"url" : "/services/api/sites/shortname"
}
[edit] MembershipDetails
Details of a site membership that includes:
- role - the role that the person plays in the site
- person - the person (see JSON defintion for person)
- url - url to the membership resource
JSON example:
{
"role" : "SiteManager",
"person" :
{
"userName" : "userId",
"url" : "/alfresco/service/api/people/userId",
"firstName" : "Bob",
"lastName" : "Smith"
},
"url" : "/alfresco/service/api/sites/mySite/memberships/userId"
}
[edit] Resources
[edit] Site Collection
The site collection contains a list of sites available across the repository. This collection may be filtered.
Methods:
GET /sites
?nf={namefilter}&spf={sitepresetfilter}
<= SiteDetails[]
POST /sites
=> SiteDetails
<= SiteDetails
[edit] Site
The site resource represents the site. This consists of a name, description and a list of memberships for that site. There will also be information about the 'owner' of the site and whether the site is public of not.
Methods:
GET /sites/{shortname}
<= SiteDetails
PUT /sites/{shortname}
=> SiteDetails
DELETE /sites/{shortname}
[edit] Site Membership Collection
The membership collection represents a list of all the membership details for a site. This collection may be filtered.
Methods:
GET /sites/{shortname}/memberships
?nf={namefilter}&rf={rolefilter}
<= MembershipDetails[]
POST /sites/{shortname}/memberships
=> MembershipDetails
[edit] Site Membership
The site membership resource represents a users membership to a site. This consists of a link to the site and the user concerned. It also contains information about the 'role' or permissions that user has on that site.
Methods:
GET /sites/{shortname}/memberships/{username}
<= MembershipDetails
PUT /sites/{shortname}/memberships/{username}
=> MembershipDetails
DELETE /sites/{shortname}/memberships/{username}
[edit] Invite Service
NOTE - the API to this interface is subject to change - please use with care.
Note that throughout this section (and the code implementing it), the word 'invite' is used within the context of its informal usage as a noun - with the same meaning as 'invitation'.
[edit] Data
[edit] InviteInfo
Information pertaining to an invite:
- Invite ID (this must be unique and always present)
- User name of inviter (invite sender)
- User name of invitee (invite recipient)
- Site (the short name of the site that the inviter is inviting the invitee to join)
- Invite URL (retrieves this InviteInfo instance)
Example of JSON representation of an InviteInfo object:
{
"inviteId" : "jbpm$98",
"inviterUserName" : "Bob.Lawrence",
"inviteeUserName" : "Tom.Richards",
"siteShortName" : "BobsBicycles",
"inviteUrl" : "/api/invites?inviteId=jbpm$98"
}
[edit] Resources
[edit] Invite Collection
An invite collection contains a list of pending invites, filtered by the parameters provided. Pending invites are those which haven't been cancelled by the inviter, or accepted or rejected by the invitee.
Methods:
Note that all the parameters for this method are optional, but at least one them must be provided
GET /invites?inviterUserName={inviterUserName}&inviteeUserName={inviteeUserName}&siteShortName={siteShortName}</url>
returns InviteInfo[]
[edit] Invite
An invite resource represents an invite, the properties of which are outlined above in InviteInfo
Methods:
TODO: Note that the method below will probably in the future be superceded by something more RESTful like [GET /invites/{inviteId} returns InviteInfo]
GET /invites?inviteId={inviteId}
returns InviteInfo
TODO: Note that the method below will probably in the future be superceded by something more RESTful like [POST /invites input InviteInfo] (though the problem with this is that I need to find some way of passing in the invitee's first name, last name and email address, which are not part of InviteInfo (and shouldn't be). Perhaps this can be achieved by the client first calling [PUT /people/{inviteeUserName} input PersonDetails], with the invitee's first name, last name, and email address included in the updated person details)
GET /invite/start?inviteeFirstName={inviteeFirstName}&inviteeLastName={inviteeLastName}&inviteeEmail={inviteeEmailAddress}&siteShortName={siteShortName}
returns InviteInfo
TODO: Note that the method below will probably in the future be superceded by something more RESTful like [DELETE /invites/{inviteId} returns InviteInfo]
GET /invite/cancel?inviteId={inviteId}
returns InviteInfo
TODO: Note that below, the parameters {inviteeUserName} and {siteShortName} shall be removed soon as they are redundant, and the values thereof should actually be looked up by the Web Script itself (as they can be looked up by using the {inviteId} parameter)
Also note that the method below will probably in the future be superceded by something more RESTful like [PUT /invites/{inviteeUserName} input InviteDetails, and including the updated state of accepted in the InviteDetails. The problem with this however is that I don't know how to perform a PUT Web Script call from a URL within the body of the invite email]
GET /inviteresponse/accept?inviteId={inviteId}&inviteeUserName={inviteeUserName}&siteShortName={siteShortName}
returns InviteInfo
TODO: The same change notifications from the previous method apply here too.
GET /invite/inviteresponse/reject
returns InviteInfo?inviteId={inviteId}&inviteeUserName={inviteeUserName}&siteShortName={siteShortName}
Getting information about an invite if the id and ticket is known:
GET api/invite/{inviteId}/{inviteTicket}
<= Invite
Note: This call does not require authentication
[edit] Person Service
[edit] Data
[edit] PersonQuery
A person query contains parameters to be used when querying the repository for people:
- part of name
- part of organisation
- part of email address
[edit] Person
Person data includes:
- unique identifier
- title
- first name
- last name
- organisation
- job title
- email address
- bio
- avatar URL
- sites - url to the collection of sites the user is an explicit member of
JSON example:
{
"userName" : "userId",
"url" : "/alfresco/service/api/people/userId",
"firstName" : "Bob",
"lastName" : "Smith",
"sites" : "/alfresco/service/api/people/userId/sites"
}
[edit] Resources
[edit] People Query
A query collection containing people in the repository that match the query parameters.
Methods:
GET /query/people => PersonQuery <= Person[]
[edit] People Collection
The people collection contains a list of all the people in the repository. This list may be filtered.
Methods:
GET /people <= Person[]
POST /people => Person <= Person
[edit] Person
The person resource represents an alfresco user.
Methods:
GET /people/{userid} => Person
PUT /people/{userid} <= Person
DELETE /people/{userid}
[edit] Persons Site Collection
A list of the sites that a person has an explicit memebership of.
Methods:
GET /people/{userid}/sites
<= Site[]
[edit] Activities Service
[edit] Assumptions (TBC)
- siteId (equivalent to site shortname) has a well-defined max length - note: activities service schema currently accommodates siteIds upto 255 characters
- userId (equivalent to person username) has a well-defined max length - note: activities service schema currently accommodates userIds upto 255 characters
[edit] Data
[edit] Feed Control
Feed control data includes:
- siteId (site shortname)
- appToolId (app/tool id)
[edit] Resources
[edit] User Feed
Get user feed entries for currently logged in user. Optionally filter by site. Required authentication = "user".
Methods:
GET /activities/feed/user
GET /activities/feed/user?s={siteId}
As currently logged in admin, get user feed entries for specified user. Optionally filter by site. Required authentication = "admin".
Methods:
GET /activities/feed/user/{userId}
GET /activities/feed/user/{userId}?s={siteId}
[edit] Site Feed
Get site feed entries for a given site. If site is private then currently logged in user must be a member of the site or an admin (else will get 401). Required authentication = "user".
Methods:
GET /activities/feed/site/{siteId}
[edit] User Feed Control
Get user feed controls for currently logged in user. Required authentication = "user".
Methods:
GET /activities/feed/controls
<= FeedControl[]
Set user feed control for currently logged in user. Required authentication = "user".
Methods:
POST /activities/feed/control
=> FeedControl
Unset user feed control for currently logged in user, for given {siteId} or given {appToolId} or given combination (if both are supplied). Required authentication = "user".
Methods:
DELETE /activities/feed/control?s={siteId}&a={appToolId}
[edit] Rendition Service (TBD)
[edit] Data Dictionary Service (TBD)
- Read access to dictionary models
[edit] Properties Service (TBD)
- read/write of node
- properties
- assocs
- etc
[edit] Thumbnail Service
[edit] Data
[edit] Thumbnail Details
Contains the name of the thumbnail and the URL to the thumbnail content. Only the thumbnail name is madatory, other data is present if appropriate.
JSON Example:
{
"thumbnailName" : "webpreview",
"url" : "/alfresco/service/api/node/workspace/SpacesStore/43170404-5d87-4d90-8587-55113bf7ec4f/content/thumbnails/webpreview"
}
[edit] Resources
[edit] Thumbnail Collection
The collection of thumbnails for a given nodes content property.
Methods:
GET /node/{store_type}/{store_id}/{id}/content{property}/thumbnails
<= ThumbnailDetails[]
GET /path/{store_type}/{store_id}/{id}/content{property}/thumbnails
<= ThumbnailDetails[]
POST /node/{store_type}/{store_id}/{id}/content{property}/thumbnails
?as={async?}
=> ThumbnailDetails (only thumnbnail name is required)
<= ThumbnailDetails
POST /path/{store_type}/{store_id}/{id}/content{property}/thumbnails
?as={async?}
=> ThumbnailDetails (only thumnbnail name is required)
<= ThumbnailDetails
[edit] Thumbnail
GET /node/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}
?qc={queuecreate?}&fc={forcecreate?}&ph={placeholder?}
<= BinaryContent | 404
GET /path/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}
?qc={queuecreate?}&fc={forcecreate?}&ph={placeholder?}
<= BinaryContent | 404
PUT /node/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}
?as={async?}
PUT /path/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}
?as={async?}
DELETE /node/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}
DELETE /path/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}
[edit] Tagging Service
[edit] Data
Also see Node
[edit] Tag Scope
{
"node" : "workspace://SpacesStore/123-123-123".
"lastupdated" : { ... date ... },
"tags" : "/../../tags"
}
[edit] Tag Map
{
"tagName1" : 12,
"tagName2" : 10,
"tagName3" : 2,
}
[edit] Resources
[edit] Tag Collection
GET /api/tags/{store_type}/{store_id}
?tf={tag_filter?}
<= String[]
GET /api/tags/{store_type}/{store_id}/{tag}/nodes
<= Node[]
GET /api/tags/{store_type}/{store_id}/{id}/{tag}/nodes
<= Node[]
[edit] Node Tag Collection
GET /api/node/{store_type}/{store_id}/{id}/tags
<= String[]
GET /api/path/{store_type}/{store_id}/{id}/tags
<= String[]
POST /api/node/{store_type}/{store_id}/{id}/tags
=> String[]
<= String[]
POST /api/path/{store_type}/{store_id}/{id}/tags
=> String[]
<= String[]
[edit] Tag Scope
TODO: The node specific urls should probably use /api/tagscopes/node/... instead of /api/tagscopes/...
POST /api/tagscopes => Node
GET /api/tagscopes/{store_type}/{store_id}/{id}
<= TagScope
DELETE /api/tagscopes/{store_type}/{store_id}/{id}
GET /api/tagscopes/{store_type}/{store_id}/{id}/tags
?tn={topN}
<= TagMap
GET /api/tagscopes/site/{short_name}/tags
?tn={topN}
<= TagMap
GET /api/tagscopes/site/{short_name}/{container}/tags
?tn={topN}
<= TagMap
[edit] Preferences Service
[edit] Data
[edit] Preference Set
{
"alfresco" :
{
"myComponent" :
{
"StringPref" : "myPrefValue",
"BooleanPref" : true
},
"myOtherComponent" :
{
"NumberPref" : 12
}
},
"myPrefWithNoNamespace" : "someValue"
}
[edit] Resources
[edit] Users Preference Set
GET /api/people/{userid}/preferences
?pf={preferencefilter?}
<= PreferenceSet
Gets all the preferences set for user. All preference values are returned in a preference set.
The name filter can be used to restrict the set of returned preferences. It can be a partial name, specifying part of the preferences namespace. (eg: ?nf=alfresco.myComponent will return just preference values for alfresco.myComponent) The full preference name can be specified to return only one preference value.
POST /api/people/{userid}/preferences
=> PreferenceSet
DELETE /api/people/{userid}/preferences
?pf={preferencefilter?}
[edit] Discussion Service
Provides methods to fetch, create and update forum posts. Posts are hierarchical, a post can be created as a reply to another post.
[edit] Data objects
=> Forum
{
"name" : "name",
}
<= Forum
{
"nodeRef" : "<nodeRef>",
"postsURI" : "URI to fetch the posts",
"name" : "myForum",
}
=> Post
{
"title" : "title",
"content" : "content",
"tags" : [ "ECM", "Alfresco" ]
}
Notes:
* "" or [] will be used for fields that are not specified
* tags sets the set of tags, replacing the old set of tags
<= Post
{
/* Top-level posts only data */
"name" : "<name of the post>",
"totalReplyCount" : 10,
"lastReplyBy" : "<date>", // only available if totalReplyCount > 0
"lastReplyOn" : "<date>", // only available if totalReplyCount > 0
"tags" : [ "Alfresco", "ECM" ],
/* Fields available for all posts */
"url" : "/api/forum/post/node/{store_type}/{store_id}/{id}",
"repliesUrl" : "/api/forum/post/node/{store_type}/{store_id}/{id}/replies",
"nodeRef" : "<nodeRef>",
"title" : "<title>",
"createdOn" : "<date>",
"modifiedOn" : "<date>",
"author" : "<username>",
"isUpdated" : true/false,
"updatedOn" : "<date>", // only available if isUpdated==true
"content" : "<content>",
"replyCount" : 10, // direct replies to this post
"permissions" : [ "edit": true, "delete" : true, "reply" : true ]
}
Notes:
* Only top-level posts support tagging for now
* Only top-level posts have totalRepliesCount, lastReplyOn, lastReplyBy fields
* In case there are no replies, lastReplyOn and lastReplyBy won't be returned
* The "name" value of top-level posts can be used as part of the path in site/container/path urls to fetch the post
<= Reply
{
/* Exactly the same information as in the post structure above */
<post properties>
/* If children are returned as well, they will be contained in following array */
children: []
}
[edit] Methods
Use following methods to create and manage forums.
Fetch all forums in the system or forums located at a specific location
GET /api/forums
<= Forum[]
GET /api/forum/node/{store_type}/{store_id}/{id}/forums
<= Forum[]
GET /api/forum/site/{site}/{container}{path?}/forums
<= Forum[]
GET /api/forum/{path}/forums
<= Forum[]
POST /api/forum/node/{store_type}/{store_id}/{id}/forums
=> Forum
<= Forum
Comment (MR): this could also be /api/node .... /forums
Get the forum details
GET /api/forum/node/{store_type}/{store_id}/{id}
<= Forum
GET /api/forum/site/{site}/{container}{path?}
<= Forum
GET /api/forum/{path}
<= Forum
Use following methods to manage forum posts:
Get all posts (optinally filtered by a tag):
GET /api/forum/node/{store_type}/{store_id}/{id}/posts?tag={tag}
<= Post[]
GET /api/forum/site/{site}/{container}{path?}/posts?tag={tag}
<= Post[]
Get new posts:
GET /api/forum/node/{store_type}/{store_id}/{id}/posts/new?numdays={numdays}
<= Post[]
GET /api/forum/site/{site}/{container}{path?}/posts/new?numdays={numdays}
<= Post[]
Get hot posts:
GET /api/forum/node/{store_type}/{store_id}/{id}/posts/hot
<= Post[]
GET /api/forum/site/{site}/{container}{path?}/posts/hot
<= Post[]
Get posts for current user:
GET /api/forum/node/{store_type}/{store_id}/{id}/posts/myposts
<= Post[]
GET /api/forum/site/{site}/{container}{path?}/posts/myposts
<= Post[]
Notes:
* All methods support pagination using startIndex and pageSize parameters
Adding a new post to a forum:
POST /api/forum/node/{store_type}/{store_id}/{id}/posts (maps to a topic/post in the forum model)
=> Post
<= Post
Fetch the replies for a post:
GET /api/forum/post/node/{store_type}/{store_id}/{id}/replies?levels={levels}
<= Reply[]
GET /api/forum/post/site/{site}/{container}{path?}/replies?levels={levels}
<= Reply[]
Notes
* You can fetch several levels of replies at once, specified by the levels param.
* If you don't specify the levels, only the direct replies are returned
Adding a reply to a post:
POST /api/forum/post/node/{store_type}/{store_id}/{id}/replies
=> Post
<= Post
Get, update and delete a post (regardless whether it is a top-level post or a reply post):
GET /api/forum/post/node/{store_type}/{store_id}/{id}
<= Post
PUT /api/forum/post/node/{store_type}/{store_id}/{id}
=> Post
<= Post
DELETE /api/forum/post/node/{store_type}/{store_id}/{id}
=> Post
<= 200|?
[edit] Blogging Service
This API provides two kind of methods:
* Management of external blog configuration data as well as publishing/updating/unpublishing a post to it * Management of blog posts (getting a list of posts in a space, creating, updating and deleting posts)
[edit] Data objects
=> ExternalBlogConfiguration
{
"type" : "<blog type, currently either "typepad" or "wordpress">",
"id" : "<id of the blog>",
"name" : "<blog name>",
"description" : "<blog description>",
"username" : "<username>",
"password" : "<password>",
}
<= ExternalBlogConfiguration
{
"blogPostsUrl" : "/api/blog/node/{store_type}/{store_id}/{id}/posts",
"type" : "<blog type, currently either "typepad" or "wordpress">",
"id" : "<id of the blog>",
"name" : "<blog name>",
"description" : "<blog description>",
"url" : "<url to the external blog>",
"username" : "<username>",
"password" : "<password>",
}
=> BlogPost
{
"draft" : false/true,
"title" : "title",
"content" : "content",
"tags" : [ "ECM", "Alfresco" ]
}
Notes:
* Once a post change from draft to non-draft it cannot be changed back to draft
* If any of the other fields is not specified, a default value ("" or []) will be used as value
<= BlogPost
{
"url" : "/api/blog/post/node/{store_type}/{store_id}/{id}",
"commentsUrl" : "/api/node/{store_type}/{store_id}/{id}/comments",
"nodeRef" : "<nodeRef>",
"name" : "<name>",
"title" : "<title>",
"content" : "<content>",
"author" : "<username>",
"createdOn" : "<date>",
"modifiedOn" : "<date>",
"permissions" : [ "edit" : true, "publishExt" : true, "delete" : true ],
"commentCount" : 10,
"tags" : [ "ECM", "Alfresco"],
/* draft or internally published */
"isDraft" : true/false,
"releasedOn" : "<date>", // only available if isDraft==false
/* Updated flag - always false for draft posts */
"isUpdated" : true/false,
"updatedOn" : "<date>", // only available if isUpdated==true
/* External publishing information */
"isPublished" : true/false,
"publishedOn" : "<date>", // only available if isPublished==true
"updatedOn" : "<date>", // only available if isPublished==true
"postId" : "<id of the external post>",
"postLink" : "<link to the post>",
"outOfDate" : true/false, // whether the external post is older than then internal post
}
Notes:
* releasedOn is only available if isDraft==false
* updatedOn is only available if isUpdated==true
* updatedOn is always false for draft posts
* publishedOn and updatedOn are only available if isPublished==true
<= PostsPerMonthData
{
"beginOfMonth" : "<date>", // date marking the begin of the month
"endOfMonth" : "<date>", // date marking the end of the month
"year" : 2008,
"month" : 6, // month index. Attention: January => 0
"postCount" : 0 // number of posts
"firstPostInMonth" : "<date>" // date of the first post
}
[edit] Methods
Get information about the external blog configuration
GET /api/blog/node/{store_type}/{store_id}/{id}
<= ExternalBlogConfiguration
GET /api/blog/site/{site}/{container}{path?}
<= ExternalBlogConfiguration
Update external blog configuration data:
PUT /api/blog/node/{store_type}/{store_id}/{id}
=> ExternalBlogConfiguration
<= ExternalBlogConfiguration
PUT /api/blog/site/{site}/{container}{path?}
=> ExternalBlogConfiguration
<= ExternalBlogConfiguration
Get a list of posts for a blog
Get all posts (optionally filtered by tag and date range):
GET /api/blog/node/{store_type}/{store_id}/{id}/posts?tag={tag}&fromDate={fromDate}&toDate={toDate}
<= BlogPost[]
GET /api/blog/site/{site}/{container}{path?}/posts?tag={tag}&fromDate={fromDate}&toDate={toDate}
<= BlogPost[]
Get new posts:
GET /api/blog/node/{store_type}/{store_id}/{id}/posts/new?numdays={numdays}
<= BlogPost[]
GET /api/blog/site/{site}/{container}{path?}/posts/new?numdays={numdays}
<= BlogPost[]
Get draft posts of the current user:
GET /api/blog/node/{store_type}/{store_id}/{id}/posts/mydrafts
<= BlogPost[]
GET /api/blog/site/{site}/{container}{path?}/posts/mydrafts
<= BlogPost[]
Get posts published by the current user:
GET /api/blog/node/{store_type}/{store_id}/{id}/posts/mypublished
<= BlogPost[]
GET /api/blog/site/{site}/{container}{path?}/posts/mypublished
<= BlogPost[]
Get externally published posts:
GET /api/blog/node/{store_type}/{store_id}/{id}/posts/publishedext
<= BlogPost[]
GET /api/blog/site/{site}/{container}{path?}/posts/publishedext
<= BlogPost[]
Get the number of posts per month:
GET /api/blog/node/{store_type}/{store_id}/{id}/postspermonth
<= PostsPerMonthData[]
GET /api/blog/site/{site}/{container}{path?}/postspermonth
<= PostsPerMonthData[]
Note:
* If the blog does not contain posts yet, an empty month object for the current month is returned
Add a blog post:
POST /api/blog/node/{store_type}/{store_id}/{id}/posts
=> BlogPost
<= BlogPost
POST /api/blog/site/{site}/{container}{path?}/posts
=> BlogPost
<= BlogPost
Get, update and delete a blog post:
GET /api/blog/post/node/{store_type}/{store_id}/{id}
<= BlogPost
GET /api/blog/post/site/{site}/{container}{path?}
<= BlogPost
PUT /api/blog/post/node/{store_type}/{store_id}/{id}
=> BlogPost
<= BlogPost
PUT /api/blog/post/site/{site}/{container}{path?}
=> BlogPost
<= BlogPost
DELETE /api/blog/post/node/{store_type}/{store_id}/{id}
=> BlogPost
<= 200|?
DELETE /api/blog/post/site/{site}/{container}{path?}
=> BlogPost
<= 200|?
[edit] Comment Service
This API allows adding comments to any node in Alfresco.
The fm:forum model is currently used to store comments. The fm:discussable aspect is added to the node and then a topic called "Comments" added to it. All comments get stored as fm:post nodes into that topic.
The advantage is that comments will also be accessible from the standard webclient.
[edit] Data objects
=> Comment
{
"title" : "title",
"content" : "content"
}
<= Comment
{
"url" : "/api/comment/node/workspace/SiteStore/fba4e60a-730b-487e-a5a1-e91d16fcc9da",
"nodeRef" : "<nodeRef>",
"name" : "<name of file representing comment>",
"title" : "title",
"content" : "Comment content, html",
"author" : "username",
"createdOn" : "<date>",
"modifiedOn" : "<date>",
"isUpdated" : true/false,
"permissions" : [
"edit": "true",
"delete" : "true"
]
}
[edit] Methods
Fetching of comments for a node
GET /api/node/{store_type}/{store_id}/{id}/comments
<= Comment[]
Adding a comment to a node
POST /api/node/{store_type}/{store_id}/{id}/comments
=> Comment
<= Comment
Getting, updating and deleting a comment:
GET /api/comment/node/{store_type}/{store_id}/{id}
<= Comment
PUT /api/comment/node/{store_type}/{store_id}/{id}
=> Comment
<= Comment
DELETE /api/comment/node/{store_type}/{store_id}/{id}
<= HTTP status

