On Sun, Sep 28, 2014 at 6:40 PM, Matt Raible <[email protected]> wrote:
> On Fri, Sep 26, 2014 at 1:48 AM, Claus Ibsen <[email protected]> wrote:
>
>> Hi
>>
>> On Thu, Sep 25, 2014 at 11:23 PM, Matt Raible <[email protected]>
>> wrote:
>> > Hey all,
>> >
>> > I'm starting to develop a new application and I'm researching using
>> Camel's REST DSL vs. Spring Boot and it's REST support. The last
>> application I wrote used Apache Camel + Spring Boot, but I only used the
>> external properties support from Boot. For this new application, I have a
>> skeleton of the previous project. The new project needs to do REST
>> (XML-based). Looking at a HelloWorld example in Spring MVC vs. Camel, I'm
>> leaning towards using Spring MVC.
>> >
>> > Camel
>> > ----
>> > @Component
>> > public class HelloWorldRoute extends RouteBuilder {
>> > @Override
>> > public void configure() throws Exception {
>> > // servlet is configured in Application.java
>> >
>> restConfiguration().component("servlet").bindingMode(RestBindingMode.json);
>> >
>> > rest("/say")
>> > .get("/hello")
>> > .to("direct:talk");
>> > from("direct:talk")
>> > .process(exchange -> {
>> > HelloWorld hw =
>> HelloWorld.builder().message("Howdy World!").build();
>> > exchange.getIn().setBody(hw);
>> > });
>> > }
>> > }
>> >
>>
>> Now its only a hello world, but you can embed the route in the rest
>> dsl directly, if you want, so its shorter
>>
>>
>> rest("/say")
>> .get("/hello")
>> .route().transform(constant("Hello
>> World"));
>>
>
> Good to know. Is it possible to return an object with the REST DSL or only
> constants?
>
Yeah you can return anything you want. A constant refers to a java
instance, so it can be anything really, in the example above its a
String, eg "xxx".
If the rest component of choice support the type, then you can just
use that, eg a JAX-RS Response instance etc.
As when you use .route() you can do all the Camel routing you want,
you can also call java beans, content based routing, recipient list,
or whatever.
>
>>
>> >
>> > Spring MVC
>> > ----
>> > @RestController
>> > @Api("Hello")
>> > public class HelloWorldController {
>> >
>> > @RequestMapping(value = "/api/hello", method = RequestMethod.GET)
>> > public HelloWorld sayHello() {
>> > return HelloWorld.builder().message("Hello
>> World").build();
>> > }
>> > }
>> >
>> >
>> > I was able to get Swagger working for both services, albeit with
>> different endpoints. One issue I found is that the "base.path" has to be
>> configured or calling the methods by clicking on buttons in Swagger UI
>> doesn't work. With Spring Boot, I'm able to configure Swagger with the
>> following:
>> >
>> > @Configuration
>> > @EnableSwagger
>> > public class SwaggerConfig implements EnvironmentAware {
>> > public static final String DEFAULT_INCLUDE_PATTERN = "/api/.*";
>> >
>> > private RelaxedPropertyResolver propertyResolver;
>> >
>> > @Override
>> > public void setEnvironment(Environment environment) {
>> > this.propertyResolver = new
>> RelaxedPropertyResolver(environment, "swagger.");
>> > }
>> >
>> > /**
>> > * Swagger Spring MVC configuration
>> > */
>> > @Bean
>> > public SwaggerSpringMvcPlugin
>> swaggerSpringMvcPlugin(SpringSwaggerConfig springSwaggerConfig) {
>> > return new SwaggerSpringMvcPlugin(springSwaggerConfig)
>> > .apiInfo(apiInfo())
>> >
>> .genericModelSubstitutes(ResponseEntity.class)
>> >
>> .includePatterns(DEFAULT_INCLUDE_PATTERN);
>> > }
>> >
>> > /**
>> > * API Info as it appears on the swagger-ui page
>> > */
>> > private ApiInfo apiInfo() {
>> > return new ApiInfo(
>> > propertyResolver.getProperty("title"),
>> >
>> propertyResolver.getProperty("description"),
>> >
>> propertyResolver.getProperty("termsOfServiceUrl"),
>> > propertyResolver.getProperty("contact"),
>> > propertyResolver.getProperty("license"),
>> >
>> propertyResolver.getProperty("licenseUrl"));
>> > }
>> > }
>> >
>> > With Camel, it's a bit less code, but if I don't override the
>> "base.path", it defaults to localhost:8080. The Spring MVC Swagger
>> implementation figures out the correct base path on its own.
>> >
>> > /**
>> > * Swagger Camel Configuration
>> > */
>> > @Bean
>> > public ServletRegistrationBean swaggerServlet() {
>> > ServletRegistrationBean swagger = new
>> ServletRegistrationBean(new SpringRestSwaggerApiDeclarationServlet(),
>> "/swagger/*");
>> > Map<String, String> params = new HashMap<>();
>> > params.put("base.path", "https://localhost:8443/rest");
>> > params.put("api.title",
>> propertyResolver.getProperty("title"));
>> > params.put("api.description",
>> propertyResolver.getProperty("description"));
>> > params.put("api.termsOfServiceUrl",
>> propertyResolver.getProperty("termsOfServiceUrl"));
>> > params.put("api.version",
>> propertyResolver.getProperty("version"));
>> > params.put("api.license",
>> propertyResolver.getProperty("license"));
>> > params.put("api.licenseUrl",
>> propertyResolver.getProperty("licenseUrl"));
>> > swagger.setInitParameters(params);
>> > return swagger;
>> > }
>> >
>> > Is it possible to improve the SpringRestSwaggerApiDeclarationServlet so
>> it gets the path from CamelServlet and it doesn't have to be hardcoded?
>> >
>>
>> Yeah sure we can look into that, and also make the java configuration
>> easier so you can use a builder instead of the map etc. Feel free to
>> log a JIRA ticket in the issue tracker
>> http://camel.apache.org/support
>
>
> Done: https://issues.apache.org/jira/browse/CAMEL-7878
--
Claus Ibsen
-----------------
Red Hat, Inc.
Email: [email protected]
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen
hawtio: http://hawt.io/
fabric8: http://fabric8.io/