Goal

In my last article I built a simple hello world Rest service with spring boot, now i want to introduce more examples trying to light up various aspects of restful service.

Used technologies

JDK 1.8
Maven 3.2

pom.xml

  <dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build> 

Model: Tutorial

package com.wstutorial.rest;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Tutorial {
	private long id ;
	private String name;
	private String author;

	public Tutorial() {
	}

	public Tutorial(long id , String name, String author) {
		this.id = id;
		this.name = name;
		this.author = author;
	}
	..
}

Resource: TutorialResource

package com.wstutorial.rest;

import java.util.List;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class TutorialResource {

	@RequestMapping(value = "/tutorials", produces = "application/json")
	public ResponseEntity> tutorials() {
		List tutorials = TestData.allTutorials();
		return new ResponseEntity>(tutorials, HttpStatus.OK);
	}

	@RequestMapping(value = "/tutorials/{id}", produces = "application/json")
	public ResponseEntity getTutorial(@PathVariable("id") long id) {
		Tutorial tutorial = TestData.tutorialById(id);
		return new ResponseEntity(tutorial, HttpStatus.OK);
	}

	@RequestMapping(value = "/tutorials", produces = "application/json", method = RequestMethod.POST)
	public ResponseEntity addTutorial(Tutorial tutorial) {
		if (tutorial == null) {
			return new ResponseEntity("Tutorial should not be null",HttpStatus.BAD_REQUEST); 
		}

		return new ResponseEntity(HttpStatus.CREATED);
	}

	@RequestMapping(value = "/tutorials", produces = "application/json", method = RequestMethod.PUT)
	public ResponseEntity updateTutorial(Tutorial tutorial) {
		return new ResponseEntity(HttpStatus.OK);
	}

	@RequestMapping(value = "/tutorials/{id}", produces = "application/json", method = RequestMethod.DELETE)
	public ResponseEntity deleteTutorial(@PathVariable("id") long id) {
		System.out.println("ID " + id + " was deleted");
		return new ResponseEntity(HttpStatus.OK);
	}

}

Set the port

server.port=10080

Rest Starter

package com.wstutorial.rest;

import com.sun.jersey.api.container.httpserver.HttpServerFactory;
import com.sun.net.httpserver.HttpServer;

public class StartRestServer {
	public static void main(String[] args) {
		HttpServer server;
		try {
			server = HttpServerFactory.create( "http://localhost:10080/api" );
			server.start();
		}catch (Exception e) {
			System.out.println("Errormessage : " + e.getMessage());
		}

	}
}

Call the urls

To obtain all tutorials: http://localhost:10080/api/tutorials
Just only one specific tutorial: http://localhost:10080/api/tutorials/2

Using curl

curl -i http://localhost:10080/api/tutorials
curl -i http://localhost:10080/api/tutorials/1
curl -H "Content-Type: application/json" -X POST -d '{"author":"Adam snake","id":"1","name":"Python Basics"}' http://localhost:10080/api/tutorials
curl -H "Content-Type: application/json" -X PUT -d '{"author":"Adam changed","id":"1","name":"Python Basics"}' http://localhost:10080/api/tutorials
curl -X DELETE http://localhost:10080/api/tutorials/1
curl -X HEAD http://localhost:10080/api/tutorials/1 (doesn't work properly)
curl -X OPTIONS http://localhost:10080/api

TestClient

package com.wstutorial.rest;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.util.List;
import java.util.Set;

import org.junit.Test;
import org.springframework.web.client.RestTemplate;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

public class TestClient {

	private String endpoint = "http://localhost:10080/api/tutorials";
	private RestTemplate template = new RestTemplate();

	@Test
	public void testGetAll() {
		ResponseEntity> response = template.exchange(endpoint,
				HttpMethod.GET, null,
				new ParameterizedTypeReference>() {});

		List tutorials = response.getBody();
		assertTrue(tutorials.size() == 3);
	}

	@Test
	public void testGetOne() {
		Tutorial tutorial = template.getForObject(endpoint + "/1", Tutorial.class);
		assertNotNull(tutorial);
		assertTrue(tutorial.getId() == 1);
	}

	@Test
	public void testPost() {
		Tutorial tutorial = new Tutorial(4, "Rest with jersey", "will john");
		ResponseEntity response = template.postForEntity(endpoint, tutorial, String.class);
		assertTrue(response.getStatusCode().equals(HttpStatus.CREATED));
	}

	@Test
	public void testPut() {
		Tutorial tutorial = new Tutorial(4, "Rest with jersey", "will john");
		template.put(endpoint, tutorial);
	}

	@Test
	public void testHead() {
		ResponseEntity response = template.exchange(endpoint, HttpMethod.HEAD, null, ResponseEntity.class);
		assertNotNull(response);
		assertTrue(response.getStatusCode() == HttpStatus.OK);
	}

	@Test
	public void testDelete() {
		template.delete(endpoint + "/1");
	}

	@Test
	public void testOptions() {
		Set optionsForAllow = template.optionsForAllow(endpoint);
		assertNotNull(optionsForAllow);
		assertTrue(optionsForAllow.contains(HttpMethod.GET));
	}
}

RestTemplate put and delete methods are void
If you want to check the response, you can use the exchange method
    @Test
	public void testDeleteWithExchange() {
		ResponseEntity response = template.exchange(endpoint + "/2", HttpMethod.DELETE, null,ResponseEntity.class);
		assertNotNull(response);
		assertTrue(response.getStatusCode() == HttpStatus.OK);
	}

References

  • RestTemplate javadoc
  • ResponseEntity javadoc