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".logging.enabled = pretty
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. |