Service endpoints and paths
Let’s explain how a service endpoint can be exposed under a certain URL path.
Set the endpoint path via application.properties
In the First SOAP Web service chapter, we explained how to expose a service using application.properties
:
# The context path under which all services will be available
quarkus.cxf.path = /soap
# Publish "HelloService" under the context path /${quarkus.cxf.path}/hello
quarkus.cxf.endpoint."/hello".implementor = io.quarkiverse.cxf.it.server.HelloServiceImpl
quarkus.cxf.endpoint."/hello".features = org.apache.cxf.ext.logging.LoggingFeature
With this setup in place, the io.quarkiverse.cxf.it.server.HelloServiceImpl
will be accessible under http://localhost:8080/soap/hello
.
This is the traditional way that worked since the very beginning of Quarkus CXF.
Set the endpoint path using @CXFEndpoint
annotation
Since Quarkus CXF 3.11.0, there is a new way to expose an endpoint under a specific path: the @io.quarkiverse.cxf.annotation.CXFEndpoint
annotation.
The path is set through its non-optional attribute value
and it is relative to quarkus.cxf.path
much like when this is done via application.properties
.
Let’s have a look at an example.
The sample code snippet shown in this section comes from the Client and server integration test in the source tree of Quarkus CXF. You may want to use it as a runnable example. |
package io.quarkiverse.cxf.it.annotation.cxfendpoint;
import jakarta.jws.WebService;
import io.quarkiverse.cxf.annotation.CXFEndpoint;
import io.quarkiverse.cxf.it.HelloService;
@CXFEndpoint("/path-annotation") (1)
@WebService(serviceName = "HelloService", targetNamespace = HelloService.NS)
public class PathAnnotationHelloServiceImpl implements HelloService {
@Override
public String hello(String person) {
return "Hello " + person + " from PathAnnotationHelloServiceImpl!";
}
}
1 | If the value of quarkus.cxf.path in application.properties is /soap ,
then this service will be accessible under http://localhost:8080/soap/path-annotation . |
@CXFEndpoint("/my-path")
annotation on MyServiceImpl
type is equivalent to the quarkus.cxf.endpoint."/my-path".implementor = org.acme.MyServiceImpl
line in application.properties
.
Therefore it is enough to use just one of them.
Other options set in application.properties
for the /my-path
endpoint will combine just fine with @CXFEndpoint("/my-path")
.
Use the @CXFEndpoint
annotation on producer methods
The @CXFEndpoint
annotation can also be used on producer methods.
This comes in handy especially when testing clients, because the returned implementation can be a mock.
Here is an example:
package io.quarkiverse.cxf.it.annotation.cxfendpoint;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import io.quarkiverse.cxf.annotation.CXFClient;
import io.quarkiverse.cxf.annotation.CXFEndpoint;
import io.quarkiverse.cxf.it.HelloService;
import io.quarkus.test.junit.QuarkusTest;
@QuarkusTest
public class MockedEndpointTest {
@CXFEndpoint("/helloMock") (1)
HelloService helloMockService() {
final HelloService result = Mockito.mock(HelloService.class);
Mockito.when(result.hello("Mock")).thenReturn("Hello Mock!");
return result;
}
@CXFClient("helloMock") (2)
HelloService helloMockClient;
@Test
void helloMock() {
Assertions.assertThat(helloMockClient.hello("Mock")).isEqualTo("Hello Mock!"); (3)
}
}
1 | Here we use the @CXFEndpoint annotation on a method that returns a mock of the HelloService interface.
The @jakarta.enterprise.inject.Produces annotation is not required, because Quarkus CXF
declares @CXFEndpoint as a bean defining annotation. |
2 | The client is configured in application.properties to connect to http://localhost:8080/soap/helloMock |
3 | The assertion makes sure that the service implementation works as expected. |