A minimal and modular REST server using XWiki components and Jax-RS.
Note: this autonomous application IS NOT an XWiki's platform extension and does not require the XWiki runtime.
- Project Lead: Guillaume Delhumeau
- Issue Tracker
- Communication: Mailing List, IRC
- License: LGPL 2.1.
- Continuous Integration Status:
Add the following dependency to your project:
<dependency>
<groupId>org.xwiki.contrib</groupId>
<artifactId>xwiki-restserver-api</artifactId>
<version>1.0</version>
</dependency>
Then, implement some REST resources by creating XWiki components (must be singleton), using the JaxRS Standard:
@Path(HelloWorldResource.PATH) // URL of the resource
@Component // Indicate it's an XWiki component
@Singleton // Only singletons are supportted
@Named(HelloWorldResource.PATH) // Don't forget to give a name to your component,
// otherwise it will overwrite the "default" component.
public class HelloWorldResource implements org.xwiki.contrib.rest.RestResource
{
public static final String PATH = "/hello";
@GET
@Produces("application/json")
@Formatted
public HelloWorld getHelloWorld()
{
return new HelloWorld("Hello World!", 1);
}
}
(don't forget to fill the components.txt
file!)
Add the following dependency to your project:
<dependency>
<groupId>org.xwiki.contrib</groupId>
<artifactId>xwiki-restserver-standalone</artifactId>
<version>1.0</version>
</dependency>
Then run a standalone server:
public static void main(String[] args)
{
try {
XWikiRestServer server = new XWikiRestServer(PORT_NUMBER, new XWikiJaxRsApplication());
server.run();
} catch (ComponentLookupException e) {
e.printStackTrace();
}
}
By default, XWikiJaxRsApplication creates its own ComponentManager. If you need to use your own ComponentManager, simply pass it to the XWikiJaxRsApplication's constructor:
XWikiJaxRsApplication application = new XWikiJaxRsApplication(componentManager);
Add the following dependency to your project:
<dependency>
<groupId>org.xwiki.contrib</groupId>
<artifactId>xwiki-restserver-users-api</artifactId>
<version>1.0</version>
</dependency>
Then, use the @Restricted
annotation in your resource:
@GET
@Produces("application/json")
@Formatted
@Restricted(groups = {"admin", "reader"}) // restricted to the "admin" and the "reader" groups
public POJO getPOJO()
{
POJO object = new POJO("Restricted Resource", 42);
return object;
}
The @Restricted
annotation takes a groups
parameter, which is a list of group names that are authorized to perform the request.
The user management is implemented in the interface RestUsersManager
, that you need to implement to map your user infrastructure (LDAP, etc...).
Add the following dependencies to your project:
<!-- Test dependencies -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.xwiki.commons</groupId>
<artifactId>xwiki-commons-tool-test-component</artifactId>
<version>7.4.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.xwiki.contrib</groupId>
<artifactId>xwiki-restserver-test</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
Then, write the functional test:
@AllComponents
public class FunctionalTest
{
/**
* Utility class to run and perform requests on a test server.
*/
private static TestServer testServer;
@BeforeClass
public static void setUp() throws Exception
{
testServer = new TestServer(new XWikiJaxRsApplication());
testServer.start();
}
@AfterClass
public static void tearDown()
{
testServer.stop();
}
@Test
public void testHelloWorldResource() throws Exception
{
// Test
String result = testServer.doGet("/hello");
// Verify
String expectedResult = "{\n"
+ " \"message\" : \"Hello World!\",\n"
+ " \"version\" : 1,\n"
+ " \"otherMessages\" : [ \"Message 1\", \"Message 2\", \"Message 3\" ]\n"
+ "}";
assertEquals(expectedResult, result);
}
}
And that's all!
You could find a more complete example in xwiki-restserver-example
, with a basic user management, unit and functional tests.