How to create class properties using the REST API?

Hi all!

First of all, as I’m new here, I want to thank all developers from XWiki SAS and all other contributors for providing this awesome platform.

I’ve been checking out the REST API and generally speaking, it works like a charm when I know how to do things - could create pages, users, attachments and so on. However, I failed to achieve the following:

Is it possible to create class properties using the REST API? I mean the action you perform when using the class editor for a page.

I checked out two main ways:

  1. Trying PUT or POST using the Class resource: ‘http://localhost:8080/rest/wikis/xwiki/classes/MyTestClass.WebHome’ or ‘http://localhost:8080/rest/wikis/xwiki/classes/MyTestClass.WebHome/properties’. While I can send GET requests, any attempts for POST or PUT requests failed (method not allowed in this context). This makes sense to me because the REST API documentation lists only GET methods for the Class resource, but I just wanted to check.
  2. Trying to create a page the normal way using a PUT request and adding a class/property section in the xml. At least that’s what the xml looks like if I send a GET request including ?class=true for a page which has a class property, so I thought this might work. That request was actually accepted, but the property I defined was not uploaded.

Adding the property as an object to the page seems to make no sense (and did not work either) as a class property isn’t a page object to my understanding.

I could provide more details but first I would like to understand which of these ways is the correct one, or maybe another, or even none, or if there’s a fundamental misconception in my thinking.

Any help greatly appreciated.

Unfortunately it’s still a (shameful) hole in that API, see Loading.... Should not be hard to add the resource for it, but just never been at the top of the TODO list.

I guess what’s needed is to add support for PUT and DELETE in xwiki-platform/xwiki-platform-core/xwiki-platform-rest/xwiki-platform-rest-api/src/main/java/org/xwiki/rest/resources/classes/ClassPropertyResource.java at master · xwiki/xwiki-platform · GitHub.

The UI uses a kind of dedicated REST API

Possible workarounds I can think of:

  • well, I guess the ideal would be to actually fix that issue and provide a pull request (and patch your instance waiting for the next release) :slight_smile:
  • exposing your own custom API as an extension you install in your XWiki instance
  • the UI which manipulate the class actually use a kind of REST API, but it’s one which takes a token that you can only get by having a foot in the instance itself since you need to call a Java/script API to get one

Thanks for the quick answer! This for the least saves me from further experimenting with the impossible. :slightly_smiling_face:

For now I think I’ll try your suggestion to call a dedicated scripted page inside the XWiki.

Just for documentation, following the suggestion from @tmortagne I arrived at the following workaround. This works completely from the REST API so I’m achieving functionally the same as if the REST endpoint I’m after would actually exist. I’m creating the scripted page from the REST API, then execute it with a GET request, then delete it. It’s kind of verbose and might be achievable in a more elegant way but I’m fine with it.

The code for the XClass creation is taken directly from the XWiki Scripting API Guide (with slight adjustments).

  1. Create a temporary class creator page

PUT request URL: ‘http://localhost:8080/rest/wikis/xwiki/spaces/Temp/pages/TempClassCreator
PUT xml file:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<page xmlns="http://www.xwiki.org">     
        <title>TemplateClassCreator</title>
        <syntax>xwiki/2.1</syntax>
        <content>{{velocity}}
#set ($mydoc = $xwiki.getDocument('Temp.MyTestClass'))
#set ($myinternaldoc = $mydoc.getDocument())
#set ($myclass = $myinternaldoc.getXClass())
#set ($discard = $myclass.addTextField("MyTestProperty", "MyTestProperty", 30))
#set ($discard = $mydoc.save('created doc + xclass'))
{{/velocity}}</content>
</page>
  1. Execute the creator page:

GET request URL: ‘http://localhost:8080/bin/get/Temp/TempClassCreator

  1. Delete the temporary class creator page (for security reasons):

DELETE request URL: ‘http://localhost:8080/rest/wikis/xwiki/spaces/Temp/pages/TempClassCreator

As for the outcome of 1.-3. I’ll have my desired class “Temp/MyTestClass”, being a terminal page, including a property “MyTestProperty” of type string with size of 30.

That’s a lot of created and delete pages (I would have seen a single persistent ClassCreator service which takes what to do as parameter), but glad you found a workaround that works for you :slight_smile: