Build a Web API in Java and Spring boot
In this article you will learn to:
- Configure your Visual Studio code environment for usage with Spring Boot.
- Create a Spring boot project.
- Learn how Spring enables you to create a REST API.
- Document your API via Swagger and Open API specification.
Further reading
- Spring boot
- What is Spring boot
- Deploy spring boot on Azure
- As this tutorial helps you create an API with an Open API spec file, you can take that and create a connector from it Create a custom connector from Open API a building block in Microsoft Power platform.
Prereqs
You should have the following installed:
- Java
- Maven, a building tool for building projects and maintaining dependencies
- Visual Studio Code
Configure Visual Studio via extensions
To make it easier to work with development of Web APIs in Java, you can install a set of extensions. These extensions will help you with tooling support around auto completion but also stopping starting and debugging your web apps.
You need these two extensions:
which will install the following:
- Java development kit JDK
- Extension Pack for Java
- Spring Boot Extension Pack, specific tooling around using Spring Boot.
To learn more on developing with Java using Visual Studio Code, go to:
Exercise: Create a Spring boot project
Once you've installed the extensions needed you can use the command palette in Visual Studio Code to scaffold your Spring Boot project.
-
Bring up the command pallette (View -> Command Palette) and choose the following command:
Spring Initializr: Create a Maven Project
Specify a Spring Boot version, select 3.0
Specify a project language Java
Input group id for your project com.example, it will scaffold up a directory structure for you as well as adding this id in the
pom.xml
file.Input Artifact Id for your project Demo
Specify packaging type Jar, you can change this later to War if you want (if you want to run your app in application server like Tomcat for example, you want a War file but for now the app will run in a built-in server)
Specify Java version
Search for dependencies, you want to add Spring Web at minimum, but might want to add other dependencies in the future like JPA, Session management and more.
Your project so far
This scaffolded a project for you. Let's go through the parts you need to know about:
src/
main/
java/
com/
example/
demo/
DemoApplication.java
resources/
application.properties
test/
As you can see above, you have structure consisting of application files, DemoApplication.java under demo/
, configuration files under resoruces/
and tests under test/
.
Application files
So far, you only have one application file DemoApplication.java which looks like so:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Demo2Application {
public static void main(String[] args) {
SpringApplication.run(Demo2Application.class, args);
}
}
This file is the entry point to your application.
Configuration
You have a configuration file application.properties that starting out is empty but will be used as you add things to your app in need of configuring for example:
- what port to start up on.
- if you got self documenting docs like Swagger.
- credentials for a database, if you're using one.
What are routes?
In a Web API there are logical areas of your application like customers, orders, products and so on. When you have the user use your app you can send the user to these logical areas by specifying routes, parts of the URL. Imagine that you have the following URL http://contoso.com and you have three areas in your app:
- customers, this is where you handle customers, adding new ones and updating existing ones.
- products, these are products the customers can buy.
- orders, these are orders the customers can place.
based on these areas, we can now create areas of our app addressing them like so:
/customers
/products
-
orders
so when a user then navigates to for example /customers
they would type in the full address http://www.contoso.com/customers but the route part would be /customers
a sub part of the URL.
We can now write code that responds to a route like the ones mentioned above.
Adding a route
To add a route, you need to create a class like so:
@RestController
public class HelloServiceController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public ResponseEntity<Object> getHello() {
return new ResponseEntity<>("hello", HttpStatus.OK);
}
}
Let's break down what's going on:
- The decorator
@RestController
ensures the class can respond to web request. -
@RequestMapping(value = "/hello", method = RequestMethod.GET)
does two things, response to a specific route "/hello" and to a specific HTTP verb, GET, which means to read data from the server. - The method
getHello()
produces a response of typeResponseEntity<Object>
and the specific call we make,return new ResponseEntity<>("hello", HttpStatus.OK)
produces a text response with code 200,HttpStatus.OK
which means everything is ok.
Now that we know how we can create code to respond to route requests, let's add code to handle /products
route in the below exercise.
Exercise: adding a route
- Create a
product
directory in the same place as your DemoApplication.java file and create the following files:
Product.java
ProductController.java
ProductRepository.java
- Give Product.java the following content:
package com.example.demo.product;
public class Product
{
private String name;
public Product(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
}
the Product
class will serve as our model.
- Give ProductRepository.java the following content:
package com.example.demo.product;
import java.util.ArrayList;
public class ProductRepository
{
private ArrayList<Product> products;
public ProductRepository()
{
this.products = new ArrayList<Product>();
this.products.add(new Product("tomato"));
}
public ArrayList<Product> getProducts()
{
return this.products;
}
}
ProductRepository
will now have one entry of type Product
.
- Give
ProductController.java
the following content:
package com.example.demo.product;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
@RestController
public class ProductController {
/**
* @return
*/
// TODO: query param, route param
@RequestMapping(value = "/products")
public ResponseEntity<ArrayList<Product>> getProducts() {
ProductRepository repo = new ProductRepository();
return new ResponseEntity<>(repo.getProducts(), HttpStatus.OK);
}
}
Now we have all the code needed to respond to a web request to /products
. Next, let's run our app:
- Select "Spring Boot dashboard" icon on the left menu in Visual Studio Code, should look like a stop icon.
- Select the play icon to start your app
- In your browser, navigate to "http://localhost:8080/products", you should see the following output:
http://localhost:8080/products
Document your API via Open API (Swagger)
Next, we want to learn how to document our API. We can use Open API to do so (formerly known as Swagger). In our pom.xml file, the file Maven uses to keep track of dependencies, we can add the following dependency:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.0.0</version>
</dependency>
this will ensure our Maven project knows how to add the capability that will give us Open API support.
On the command line, you can now type:
mvn package
which will fetch all dependencies (if not fetched already) and add package your project into a Jar file.
Open API
This dependency will do two things for us:
- Create an Open API specification, a JSON file that describes our API, that can be used to create a connector for Microsoft Power Platform for example or in other ways help describe how to work with our API.
- Create a a UI that we can interact with to test our interface.
Exercise: add Open API
- Add the following XML to the
dependencies
section of your pom.xml:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.0.0</version>
</dependency>
- Run
mvn package
in the command line - In resources directory, locate application.properties and add the following content:
springdoc.api-docs.path=/docs
springdoc.swagger-ui.path=/swagger.html
this will ensure we can find our Open API spec file at /docs
and our UI at swagger.html
Start the app again via the Spring boot dashboard icon in Visual Studio Code:
Navigate to "http://localhost:8080/docs", you should see a JSON output similar to below, i.e our specification file:
{"openapi":"3.0.1",
"info":{"title":"OpenAPI definition","version":"v0"},"servers":[
{ "url":"http://localhost:8080",
"description":"Generated server url"}],
"paths":{
"/hello":{"get":{
"tags":["hello-service-controller"],"operationId":"getHello",
"responses":{
"200":{
"description":"OK",
"content":{
"*/*":{"schema":{"type":"object"}}}}}
}},
"/products":{
"get":{"tags":["product-controller"], "operationId":"getProducts",
"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Product"}}}}}}},
"put":{"tags":["product-controller"],"operationId":"getProducts_3",
"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Product"}}}}}}},
"post":{"tags":["product-controller"],"operationId":"getProducts_2",
"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Product"}}}}}}},
"delete":{"tags":["product-controller"],"operationId":"getProducts_5",
"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Product"}}}}}}},
"options":{"tags":["product-controller"],"operationId":"getProducts_6",
"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Product"}}}}}}},
"head":{"tags":["product-controller"],"operationId":"getProducts_1",
"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Product"}}}}}}},
"patch":{"tags":["product-controller"],"operationId":"getProducts_4",
"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Product"}}}}}}}}},
"components":{"schemas":{"Product":{"type":"object","properties":{"name":{"type":"string"}}}}}}
- Navigate to http://localhost:8080/swagger.html this will present you with a graphical view, where you can try out your API.
Congrats, you've managed to build a Web API support the route /products
but you also managed to document it using Open API. You are know well setup do extend it further and add data source to it with for example JPA (Java Persistence API), which we will cover in our next article.