How YOU can build a Web API in Java and Spring boot
Published Dec 06 2022 01:55 PM 1,061 Views
Microsoft
 

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

Prereqs

You should have the following installed:

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:

https://code.visualstudio.com/docs/java/java-spring-boot

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.

  1. Bring up the command pallette (View -> Command Palette) and choose the following command:

    Spring Initializr: Create a Maven Project
    
  2. Specify a Spring Boot version, select 3.0

  3. Specify a project language Java

  4. 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.

  5. Input Artifact Id for your project Demo

  6. 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)

  7. Specify Java version

  8. 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 type ResponseEntity<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

  1. Create a product directory in the same place as your DemoApplication.java file and create the following files:
   Product.java
   ProductController.java
   ProductRepository.java
 
  1. 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.

  1. 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.

  1. 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:

  1. Select "Spring Boot dashboard" icon on the left menu in Visual Studio Code, should look like a stop icon.
  2. Select the play icon to start your app
  3. In your browser, navigate to "http://localhost:8080/products", you should see the following output:
[{"name":"tomato"}]
 

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

  1. 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>
 
  1. Run mvn package in the command line
  2. 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

  1. Start the app again via the Spring boot dashboard icon in Visual Studio Code:

  2. 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"}}}}}}
 
  1. 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.

Co-Authors
Version history
Last update:
‎Dec 06 2022 02:46 PM
Updated by: