WeDeploy Spring Boot REST

There is a new player around named wedeploy. This is a simple example to show how you can use it.

Let's build a Spring Boot Java REST project to publish some Chuck Norris IT facts.

mkdir wedeploy-norrisws && cd wedeploy-norrisws && curl -s https://start.spring.io/starter.tgz -d dependencies=web -d language=java -d javaVersion=1.8 -d type=gradle-project -d groupId=foo -d artifactId=bar -d version=1.0 -d packageName=foo.bar -d name=wedeploy-norrisws -d description="Chuck Norris REST" -d applicationName=App | tar -xzvf - 

We need to add 3 things:

1.- A gradle dependency to generate random facts about Chuck Norris

compile('com.github.javafaker:javafaker:0.13')

2.- A controller to publish that facts.

package foo.bar.controller;

import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.github.javafaker.Faker;

@RestController
public class DataController {
    @RequestMapping(value = "/chuck/norris", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public ResponseEntity<?> index() {
        Faker faker = new Faker();
        Map<String, String> out = new LinkedHashMap<>();
        out.put("funFact", faker.chuckNorris().fact());
        return ResponseEntity.ok().body(out);
    }
}

3.- And an error controller to jsonify the errors.

package foo.bar.controller;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.ServletRequestAttributes;

@RestController
@RequestMapping("/error")
public class SimpleErrorController implements ErrorController {
    private final ErrorAttributes errorAttributes;

    @Autowired
    public SimpleErrorController(ErrorAttributes errorAttributes) {
        Assert.notNull(errorAttributes, "ErrorAttributes must not be null");
        this.errorAttributes = errorAttributes;
    }

    @Override
    public String getErrorPath() {
        return "/error";
    }

    @RequestMapping
    public Map<String, Object> error(HttpServletRequest aRequest) {
        Map<String, Object> body = getErrorAttributes(aRequest, getTraceParameter(aRequest));
        String trace = (String) body.get("trace");
        if (trace != null) {
            String[] lines = trace.split("\n\t");
            body.put("trace", lines);
        }
        return body;
    }

    private boolean getTraceParameter(HttpServletRequest request) {
        String parameter = request.getParameter("trace");
        if (parameter == null) {
            return false;
        }
        return !"false".equals(parameter.toLowerCase());
    }

    private Map<String, Object> getErrorAttributes(HttpServletRequest aRequest, boolean includeStackTrace) {
        RequestAttributes requestAttributes = new ServletRequestAttributes(aRequest);
        return errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace);
    }
}

To build and run the Spring Boot project

./gradlew clean build bootRun

You can access the endpoint with curl

curl -i http://localhost:8080/chuck/norris
HTTP/1.1 200 
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 18 Oct 2017 11:51:06 GMT

{"funFact":"Chuck Norris can divide by zero."}

or opening http://localhost:8080/chuck/norris in a browser.

Before you continue, you have to:

1.- Create a free account at https://console.wedeploy.com/signup.

2.- Install the wedeploy client

curl https://cdn.wedeploy.com/cli/latest/wedeploy.sh -sL | bash

3.- Add a wedeploy.json file

{
  "id": "app",
  "memory": 1024
}

4.- Edit the build.gradle file as:

group = 'foo'
version = '1.0'

buildscript {
	ext {
	  springBootVersion = '1.5.8.RELEASE'
	}
	repositories {
	  mavenLocal()
          mavenCentral()
          maven { url "http://repo.spring.io/release" }
	}
	dependencies {
	  classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
	}
}

apply plugin: 'java'
apply plugin: org.springframework.boot.gradle.plugin.SpringBootPlugin

sourceCompatibility = 1.8

task run(dependsOn: ':bootRun') {
  doLast {
    println 'Boot'
  }
}

repositories {
  mavenLocal()
  mavenCentral()
  maven { url "http://repo.spring.io/release" }
}

dependencies {
  compile('org.springframework.boot:spring-boot-starter-web')
  compile('com.github.javafaker:javafaker:0.13')
}

task wrapper(type: Wrapper) {
  gradleVersion = '3.5.1'
}

5.- As you can see there is no test dependency, so remove the test directory

rm -rf src/test

5.- Log in your wedeploy account in a browser and create a new project.

6.- Log in your wedeploy account using the we client

we login --no-browser

7.- Deploy the project using the we client

we deploy projectName

where projectName is the project name you created in the step 5.

When the deployment is done, you will see something like:

we deploy -p norrisws
Deploying services on project norrisws in wedeploy.com...
! Deployment successful in 2m48s
! Upload completed in 47s
! Deployed app-norrisws.wedeploy.io

Finally, you and everybody out there could access your REST endpoint.

In my case is:

curl -ki https://app-norrisws.wedeploy.io/chuck/norris
HTTP/1.1 200 
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 18 Oct 2017 12:40:14 GMT

{"funFact":"Chuck Norris does not use revision control software. None of his code has ever needed revision."}

or via browser at https://app-norrisws.wedeploy.io/chuck/norris

The code is available at https://github.com/immontilla/wedeploy-norrisws.git