Home / Companies / Aerospike / Blog / Post Details
Content Deep Dive

Building a RESTful Web Service with Spring Boot and Aerospike

Blog post from Aerospike

Post Details
Company
Date Published
Author
Peter Milne
Word Count
3,304
Company Posts That Month
1
Language
English
Hacker News Points
-
Post removed?
No
Summary

This is the complete example code for building a RESTful web service with Spring Boot that connects to an Aerospike database. 1. pom.xml ```xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.aerospike</groupId> <artifactId>aerospike-restful-example</artifactId> <version>1.0.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>0.5.0.M4</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>com.aerospike</groupId> <artifactId>aerospike-client</artifactId> <version>3.0.9</version> </dependency> <dependency> <groupId>commons-cli</groupId> <artifactId>commons-cli</artifactId> <version>1.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <url>http://repo.spring.io/libs-snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-snapshots</id> <url>http://repo.spring.io/libs-snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> </pluginRepositories> </project> ``` 2. JSONRecord.java ```java package com.aerospike.client.rest; import java.util.Map; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import com.aerospike.client.Record; /** * JSONRecord is used to convert an Aerospike Record * returned from the cluster to JSON format * */ @SuppressWarnings("serial") public class JSONRecord extends JSONObject { @SuppressWarnings("unchecked") public JSONRecord(Record record){ put("generation", record.generation); put("expiration", record.expiration); put("bins", new JSONObject(record.bins)); if (record.duplicates != null){ JSONArray duplicates = new JSONArray(); for (Map<String, Object> duplicate : record.duplicates){ duplicates.add(new JSONObject(duplicate)); } put("duplicates", duplicates); } } } ``` 3. RESTController.java ```java package com.aerospike.client.rest; import java.io.BufferedReader; import java.io.InputStreamReader; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; 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.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import com.aerospike.client.AerospikeClient; import com.aerospike.client.Bin; import com.aerospike.client.Key; import com.aerospike.client.Record; import com.aerospike.client.policy.Policy; import com.aerospike.client.policy.WritePolicy; @Controller public class RESTController { @Autowired AerospikeClient client; @RequestMapping(value="/as/{namespace}/{set}/getAll/{key}", method=RequestMethod.GET) public @ResponseBody JSONRecord getAll(@PathVariable("namespace") String namespace, @PathVariable("set") String set, @PathVariable("key") String keyvalue) throws Exception { Policy policy = new Policy(); Key key = new Key(namespace, set, keyvalue); Record result = client.get(policy, key); return new JSONRecord(result); } /* * CSV flights file upload */ @RequestMapping(value="/uploadFlights", method=RequestMethod.GET) public @ResponseBody String provideUploadInfo() { return "You can upload a file by posting to this same URL."; } @RequestMapping(value="/uploadFlights", method=RequestMethod.POST) public @ResponseBody String handleFileUpload(@RequestParam("name") String name, @RequestParam("file") MultipartFile file){ if (!file.isEmpty()) { try { WritePolicy wp = new WritePolicy(); String line = ""; BufferedReader br = new BufferedReader(new InputStreamReader(file.getInputStream())); while ((line = br.readLine()) != null) { // use comma as separator String[] flight = line.split(","); /* * write the record to Aerospike * NOTE: Bin names must not exceed 14 characters */ client.put(wp, new Key("test", "flights",flight[0].trim() ), new Bin("YEAR", Integer.parseInt(flight[1].trim())), new Bin("DAY_OF_MONTH", Integer.parseInt(flight[2].trim())), new Bin("FL_DATE", flight[3].trim()), new Bin("AIRLINE_ID", Integer.parseInt(flight[4].trim())), new Bin("CARRIER", flight[5].trim()), new Bin("FL_NUM", Integer.parseInt(flight[6].trim())), new Bin("ORI_AIRPORT_ID", Integer.parseInt(flight[7].trim())), new Bin("ORIGIN", flight[8].trim()), new Bin("ORI_CITY_NAME", flight[9].trim()), new Bin("ORI_STATE_ABR", flight[10].trim()), new Bin("DEST", flight[11].trim()), new Bin("DEST_CITY_NAME", flight[12].trim()), new Bin("DEST_STATE_ABR", flight[13].trim()), new Bin("DEP_TIME", Integer.parseInt(flight[14].trim())), new Bin("ARR_TIME", Integer.parseInt(flight[15].trim())), new Bin("ELAPSED_TIME", Integer.parseInt(flight[16].trim())), new Bin("AIR_TIME", Integer.parseInt(flight[17].trim())), new Bin("DISTANCE", Integer.parseInt(flight[18].trim())) ); System.out.println("Flight [ID= " + flight[0] + " , year=" + flight[1] + " , DAY_OF_MONTH=" + flight[2] + " , FL_DATE=" + flight[3] + " , AIRLINE_ID=" + flight[4] + " , CARRIER=" + flight[5] + " , FL_NUM=" + flight[6] + " , ORIGIN_AIRPORT_ID=" + flight[7] + "]"); } br.close(); return "You successfully uploaded " + name; } catch (Exception e) { return "You failed to upload " + name + " => " + e.getMessage(); } } else { return "You failed to upload " + name + " because the file was empty."; } } } ``` 4. AerospikeRESTfulService.java ```java package com.aerospike.client.rest; import java.util.Properties; import javax.servlet.MultipartConfigElement; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import com.aerospike.client.AerospikeClient; import com.aerospike.client.AerospikeException; @Configuration @EnableAutoConfiguration @ComponentScan public class AerospikeRESTfulService { @Bean public AerospikeClient asClient() throws AerospikeException { Properties as = System.getProperties(); return new AerospikeClient(as.getProperty("seedHost"), Integer.parseInt(as.getProperty("port"))); } @Bean public MultipartConfigElement multipartConfigElement() { return new MultipartConfigElement(""); } public static void main(String[] args) throws ParseException { Options options = new Options(); options.addOption("h", "host", true, "Server hostname (default: localhost)"); options.addOption("p", "port", true, "Server port (default: 3000)"); // parse the command line args CommandLineParser parser = new PosixParser(); CommandLine cl = parser.parse(options, args, false); // set properties Properties as = System.getProperties(); String host = cl.getOptionValue("h", "localhost"); as.put("seedHost", host); String portString = cl.getOptionValue("p", "3000"); as.put("port", portString); // start app SpringApplication.run(AerospikeRESTfulService.class, args); } } ``` 5. FlightsUploader.java ```java package com.aerospike.client.rest; import org.junit.Before; import org.junit.Test; import org.springframework.core.io.FileSystemResource; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; public class FilghtsUploader { private static final String TEST_FILE = "flights_from.csv"; @Before public void setUp() throws Exception { } @Test public void upload() { RestTemplate template = new RestTemplate(); MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>(); parts.add("name", TEST_FILE); parts.add("file", new FileSystemResource(TEST_FILE)); String response = template.postForObject("http://localhost:8080/uploadFlights", parts, String.class); System.out.println(response); } } ```

Trends Found in this Post

No tracked trend matches for this post yet.

Use This Data

Use this post, company, and trend context to find content marketing opportunities, perform competitive analysis, or address product feature gaps via the Plushcap MCP server or the Plushcap API.