v 3.7.1 - REST API Question(s)

30 views
Skip to first unread message

Henry Versemann

unread,
Jan 2, 2018, 12:53:20 PM1/2/18
to dot...@googlegroups.com

I’m currently able to use a GET/inquire request to the REST API to retrieve a contentlet.

 

Once I have it then is it possible to change a value in the contentlet, and then do a POST to update the newly changed contentlet?  

 

The value(s) I want to try to change are publish/unpublish/archive/unarchive/delete flags or values, that would mimic the manual process of doing an unpublish, archive, and then delete of entries manually.

 

Or instead of trying to do the delete process programmatically(especially if it’s not possible currently), what would be the best way to update an entry to indicate that it needs to be deleted in the future?

 

Thanks.

 

Henry

 

 

Chris Falzone

unread,
Jan 2, 2018, 4:08:47 PM1/2/18
to dot...@googlegroups.com
When you make an update you specify it is should be working or live by using save or publish parmaters:

Though, I don't think you can unpub/archive/delete content via the rest api directly.  But I know you can using workflow actions:

So just execute the proper workflow task that does it for you.  

--
http://dotcms.com - Open Source Java Content Management
---
You received this message because you are subscribed to the Google Groups "dotCMS User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dotcms+un...@googlegroups.com.
To post to this group, send email to dot...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dotcms/CY4PR0501MB377737163D54AE27CAA5BF15AD190%40CY4PR0501MB3777.namprd05.prod.outlook.com.
For more options, visit https://groups.google.com/d/optout.

Henry Versemann

unread,
Jan 2, 2018, 4:30:10 PM1/2/18
to dot...@googlegroups.com

Chris,

 

I’ve looked in the documentation and the only example I saw was one that looked like it executed just one subaction of a particular workflow like this:

 

PUT /api/content/Assign%20for%20Review/1/wfActionComments/Hey%2C%20take%20a%20look/wfActionAssign/dotCMS.org.7575

 

But it doesn’t to explain all of the parts of the URI shown, unless there are more detailed examples of calling a workflow through the REST API.

 

So I have questions about the above URI.

 

1.)    Is the actual sub-action to be executed this part of the URI: /Assign%20for%20Review/

2.)    wfActionComments’ indicates that what follows it in the next part of the URI ( /Hey%2C%20take%20a%20look/ ) is a comment right? If so is it mandatory for comments to always be declared and formatted this way and in this same position?

3.)    So is the /wfActionAssign/ part of the URI the name of the actual workflow/workflow scheme?

4.)    I’m Assuming that when a workflow scheme is created, then that workflow scheme must also be associated with the content type to be operated on, before it can be called via the REST API. Correct?

5.)    And finally in the example above is the last part of the URI above ‘dotCMS.org.7575’ always a content identifier of the contentlet to be operated on, by the workflow?

 

Let me know when you can.

Thanks.

 

Henry

Chris Falzone

unread,
Jan 3, 2018, 8:00:59 AM1/3/18
to dot...@googlegroups.com
I'm not sure on all of the details without further poking into it.  TBH, what I would do is put a boolean field as sort of an "Active" field.  Instead of dealing with publishing/archiving in the Rest API. That is what I do with our Agent Profile Contentlets.  We have a field called "isActive" and the website checks if that is set before showing the Agent Profile on the website.  The Rest API just updates that field when the user deactivates their profile.  Our use case doesn't require us to actually delete the content.  But you could do a "toDelete" field and have someone (or a script) go in and delete them once a week or on some schedule as long as your front-end code that displays the content properly handles the content state.  

That being said ...
1) Yes, just url encode the name of the action here.  All the parameters and values have to be urlencoded properly.
2) I think comments are optional.  But only allowed when the "Allow Comments" checkbox on the workflow action is checked.
3) I think the user assignment is also optional. There is "User can Assign" checkbox on the workflow action.
4) Yes, I would also assume that.
5) The last parameter there is the value to "wfActionAssign", that is the user id the content is being assigned to.  In your use-case I do not think you need this parameter or value pair.

Hope that helps.

Henry Versemann

unread,
Jan 3, 2018, 8:47:00 AM1/3/18
to dot...@googlegroups.com

Chris,

 

I asked question 5 because if I don’t supply an identifier, for the content to be operated on then how will the workflow know which contentlet it is to apply itself?

 

And are the “wfActionComments” and “wfActionAssign” strings like hard-coded keys of those key/value pairs?

 

Let me know when you can and thanks for the explanations thus far.

Chris Falzone

unread,
Jan 3, 2018, 9:39:40 AM1/3/18
to dot...@googlegroups.com
You are adding these parameters to an update. Instead of updating the content with the publish or save endpoints, you are using the Workflow Action Name as the endpoint.  In either case the identifier you are updating needs to be passed as part of the json data for the content.  

For example, instead of updating the content this way ...
curl -v -u "ad...@dotcms.com:admin" -XPUT http://demo.dotcms.com/api/content/publish/1 -F 'json={"identifier":"XXX",...};type=application/json'

you replace publish with the workflow step like this ...
curl -v -u "ad...@dotcms.com:admin" -XPUT http://demo.dotcms.com/api/content/workflow%20action%20name -F 'json={"identifier":"XXX",...};type=application/json'

Also according to the endpoints doc, the other parameters are optional (and yes I think the names are hardcoded keys):
Look at the "singlePUT" and "singlePost" endpoints.  




Henry Versemann

unread,
Jan 3, 2018, 9:46:09 AM1/3/18
to dot...@googlegroups.com

Chris,

 

So if I understand you right then the comments key/value pair and the id key/value pair would be inside a json object then in the request body right?

Chris Falzone

unread,
Jan 3, 2018, 9:54:37 AM1/3/18
to dot...@googlegroups.com
I think as part of the endpoint url, not in the json.  But, I could be wrong.  It is possible that it doesn't matter. 
Not sure that helps much.  

Nathan Keiter

unread,
Jan 3, 2018, 11:32:59 AM1/3/18
to dot...@googlegroups.com

I believe that last part is the user id to assign the workflow to. “dotCMS.org.7575”

 

Nathan I. Keiter | Lead Network Applications Programmer | Benefits Advisory Council Member | I.D.E.A Council Member
Gettysburg College | Information Technology | DataSystems
Campus Box 2453 | 300 North Washington Street | Gettysburg, PA 17325
Phone: 717.337.6993

https://www.gettysburg.edu

Henry Versemann

unread,
Jan 3, 2018, 11:39:12 AM1/3/18
to dot...@googlegroups.com

Nathan,

 

In my particular situation I’m trying to delete a particular item contentlet from its structure, by way of the REST API.

So I was hoping to pass the contentlet id value to my workflow using the “wfActionAssign” key, so the workflow would only operate on that single piece of content.

 

Is that the way to do it then?

And should I include it in the request as part of the URL, or as a key/value pair in a json object?

 

Henry

Nathan Keiter

unread,
Jan 3, 2018, 12:02:52 PM1/3/18
to dot...@googlegroups.com

Henry Versemann

unread,
Jan 3, 2018, 12:31:46 PM1/3/18
to dot...@googlegroups.com

So my workflow scheme that I’m trying to use and call the action from is named “REST API Test”.

It has two workflow steps defined within it.

The first step name is “Lock” and contains an action named “REST API Lock Employee” which has only one sub-action of “Lock content”.

The second step is “Delete” and contains an action named “REST API Delete Employee” which has only one sub-action of “Delete content”.

I think I read in the documentation that a “Delete content” sub-action will automatically do an Unpublish, an Archive, and a Delete all in one call, so that’s what I’m hoping to do when calling my “REST API Delete Employee” action and here’s what my latest request looks like(minus the domain):

 

/api/content/REST%20API%20Delete%20Employee/1/wfActionComments/Deleted%20Employee%20Contentlet%20ID%20of%20%289554f6e0-8dc4-4d36-a033-f9a09ab2ddf0%29%2E/wfActionAssign/9554f6e0-8dc4-4d36-a033-f9a09

ab2ddf0

 

using the suggested format with both comments and the identifier showing as part of the URL. I’m also using the PUT method with this request.

I’m also using only two headers, with this request. One for my authorization header and an “Accept” header for “text/plain” which seems to be common.

So far when I try to call the delete action mentioned above I’ve gotten this web exception:

 

WARNING: Delete-Employee-PSItemString=HTTP Status 400 - Bad Request

 

type Status report

message Bad Request

description The request sent by the client was syntactically incorrect.

 

 

 

Apache Tomcat/8.0.18

WARNING: Delete-Employee-InvocationInfo=System.Management.Automation.InvocationInfo

WARNING: Delete-Employee-ExceptionMessage=The remote server returned an error: (400) Bad Request.

WARNING: Delete-Employee-InnerException=

WARNING: Delete-Employee-ExceptionStacktrace=   at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.GetResponse(WebRequest request)

   at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.ProcessRecord()

WARNING: Delete-Employee-ScriptStackTrace=at Delete-Employee, C:\Users\hversemann\CAMPUS_DIRECTORY_AUTO_UPDATE_PROJECT\CAMPUS_DIRECTORY_UPDATE_AUTOMATION\Staging_PartTimeEmployeeUpdates_UsingWebRequest4_12212017.ps1: line 337

at ReadAddUpdate-File, C:\Users\hversemann\CAMPUS_DIRECTORY_AUTO_UPDATE_PROJECT\CAMPUS_DIRECTORY_UPDATE_AUTOMATION\Staging_PartTimeEmployeeUpdates_UsingWebRequest4_12212017.ps1: line 957

at <ScriptBlock>, C:\Users\hversemann\CAMPUS_DIRECTORY_AUTO_UPDATE_PROJECT\CAMPUS_DIRECTORY_UPDATE_AUTOMATION\Staging_PartTimeEmployeeUpdates_UsingWebRequest4_12212017.ps1: line 1033

WARNING: ReadAddUpdate-File-PSItemString=The remote server returned an error: (400) Bad Request.

WARNING: ReadAddUpdate-File-InvocationInfo=System.Management.Automation.InvocationInfo

WARNING: ReadAddUpdate-File-ExceptionMessage=The remote server returned an error: (400) Bad Request.

WARNING: ReadAddUpdate-File-InnerException=

WARNING: ReadAddUpdate-File-ExceptionStacktrace=   at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.GetResponse(WebRequest request)

   at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.ProcessRecord()

WARNING: ReadAddUpdate-File-ScriptStackTrace=at Delete-Employee, C:\Users\hversemann\CAMPUS_DIRECTORY_AUTO_UPDATE_PROJECT\CAMPUS_DIRECTORY_UPDATE_AUTOMATION\Staging_PartTimeEmployeeUpdates_UsingWebRequest4_12212017.ps1: line 416

at ReadAddUpdate-File, C:\Users\hversemann\CAMPUS_DIRECTORY_AUTO_UPDATE_PROJECT\CAMPUS_DIRECTORY_UPDATE_AUTOMATION\Staging_PartTimeEmployeeUpdates_UsingWebRequest4_12212017.ps1: line 957

at <ScriptBlock>, C:\Users\hversemann\CAMPUS_DIRECTORY_AUTO_UPDATE_PROJECT\CAMPUS_DIRECTORY_UPDATE_AUTOMATION\Staging_PartTimeEmployeeUpdates_UsingWebRequest4_12212017.ps1: line 1033

The remote server returned an error: (400) Bad Request.

At C:\Users\hversemann\CAMPUS_DIRECTORY_AUTO_UPDATE_PROJECT\CAMPUS_DIRECTORY_UPDATE_AUTOMATION\Staging_PartTimeEmployeeUpdates_UsingWebRequest4_12212017.ps1:1000 char:9

+         throw $_.Exception

+         ~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : OperationStopped: (:) [], WebException

    + FullyQualifiedErrorId : The remote server returned an error: (400) Bad Request.

 

So I’m trying to figure out how to change my request, to be more syntactically correct.

Any thoughts on some more things or format variations that I can try?

Thanks for the help.

Chris Falzone

unread,
Jan 4, 2018, 10:12:59 AM1/4/18
to dot...@googlegroups.com
Your Endpoint is just:  /api/content/REST%20API%20Delete%20Employee
in the json payload you put the identifier like: json={"identifier":"9554f6e0-8dc4-4d36-a033-f9a09"}

So via curl would look something like:
curl -v -u "ad...@dotcms.com:admin" -XPUT http://demo.dotcms.com/api/content/REST%20API%20Delete%20Employee -F 'json={"identifier":"9554f6e0-8dc4-4d36-a033-f9a09"};type=application/json'

You probably need to (at least) also pass any required fields as well as the languageId of the content in the json payload.


Nathan Keiter

unread,
Jan 4, 2018, 10:15:41 AM1/4/18
to dot...@googlegroups.com

That’s pretty cool Chris. I didn’t see anything about delete in the documentation.

 

Nathan I. Keiter | Lead Network Applications Programmer | Benefits Advisory Council Member | I.D.E.A Council Member
Gettysburg College | Information Technology | DataSystems
Campus Box 2453 | 300 North Washington Street | Gettysburg, PA 17325
Phone: 717.337.6993

https://www.gettysburg.edu

 

Henry Versemann

unread,
Jan 4, 2018, 10:18:21 AM1/4/18
to dot...@googlegroups.com

Chris,

 

So for a delete action what else besides maybe language id would be required for a delete?

The fields marked in red in the backend when I open up an entry for the structure in question, or something more than those?

Thanks for the help.

 

Henry

 

Chris Falzone

unread,
Jan 4, 2018, 10:20:34 AM1/4/18
to dot...@googlegroups.com
Yeah, there are a lot of ways to handle it, but it doesn't out of the box.  We use a flag and clean them up later.  I've also made a my own REST API Endpoint to delete files by inode because we needed to be able to do that in our deploy script from jenkins.  So multiple ways to handle it, but I think the "stock" way would be workflows right now. 

Chris Falzone

unread,
Jan 4, 2018, 10:23:30 AM1/4/18
to dot...@googlegroups.com
I am not 100% sure since I have not tested it.  But looking at the code, it is basically saving a new version of the content with the workflow task id associated which on save triggers the workflow.  In order to save the content you would need to pass all of the fields that you have set as required.  Personally I would just send the entire content object, but I suppose if the idea is to delete it, that might not be necessary.  Since it is identifier based, you also need languageId to make it unique.  Just assumptions since I have not tried it for myself.

Henry Versemann

unread,
Jan 4, 2018, 10:25:18 AM1/4/18
to dot...@googlegroups.com

OK thanks.

I’ll try it and see what happens.

Reply all
Reply to author
Forward
0 new messages