Mark As Completed Discussion

Introduction to APIs

APIs (Application Programming Interfaces) are an integral part of modern application development. They allow different software systems to communicate and interact with each other, enabling developers to build powerful and interconnected applications.

At a high level, an API acts as a contract between two software components. One component, known as the provider, exposes a set of functionalities or data that can be accessed and utilized by another component, known as the consumer.

APIs enable developers to:

  • Extend the functionality of their applications by integrating with external services or libraries.
  • Reuse code and resources by encapsulating complex functionalities into modular and reusable components.
  • Promote collaboration and allow different teams or individuals to work on different parts of an application simultaneously.

APIs are used extensively in various domains, such as web development, mobile app development, and enterprise software development. They play a critical role in enabling communication and interoperability between different technologies and platforms.

To get started with APIs, you need to have a basic understanding of programming concepts and the language or framework you are working with. For example, in Java and Spring Boot, you can define APIs using annotations and classes to expose endpoints that handle HTTP requests.

Let's start exploring APIs by writing a simple Java program that outputs "Hello, APIs!":

TEXT/X-JAVA
1{{code}}
JAVA
OUTPUT
:001 > Cmd/Ctrl-Enter to run, Cmd/Ctrl-/ to comment

Are you sure you're getting this? Click the correct answer from the options.

Which of the following best describes an API?

Click the option that best answers the question.

  • A type of programming language
  • A communication protocol
  • A set of functions or methods that allow different software systems to interact with each other
  • A type of database

Building a Simple API in Spring Boot

In this section, we will dive into creating a basic RESTful API using the Spring Boot framework. We will explore the fundamental concepts and techniques for developing APIs, with a focus on building a simple but functional API.

As a senior engineer with one year of experience in Java, Spring Boot, and MySQL, you are already familiar with the basics of these technologies. Building a simple API in Spring Boot will further enhance your skills and help you become a better programmer.

To get started, let's take a look at the structure of a Spring Boot API project and the main components involved.

Structure of a Spring Boot API Project

A typical Spring Boot API project follows a well-defined structure that organizes the code and resources in a modular and maintainable way. Here is an overview of the main components:

  1. Controller: The controller handles incoming HTTP requests and contains the endpoints that define the API's functionality. It acts as the entry point for handling client requests.

  2. Service: The service layer contains the business logic of the application. It is responsible for implementing the core functionalities that the API provides. It interacts with the repository layer to perform CRUD (Create, Read, Update, Delete) operations on the data.

  3. Repository: The repository layer is responsible for interacting with the database or any other external data source. It provides an interface for performing CRUD operations on the data.

  4. Model: The model consists of classes that represent the data entities of the application. It defines the structure and behavior of the data objects used in the API.

Creating a Simple API

To create a simple API in Spring Boot, we will start by setting up a new Spring Boot project and adding the necessary dependencies. We will then create the main components of the API and implement the basic CRUD operations.

  1. Setting up a Spring Boot Project: To create a new Spring Boot project, you can use Spring Initializr or your preferred IDE. Make sure to include the necessary dependencies, such as spring-boot-starter-web for building RESTful APIs and spring-boot-starter-data-jpa for working with databases.

  2. Creating the Controller: Create a new Java class to serve as the controller for the API. Annotate the class with @RestController to indicate that it handles RESTful requests. Define the endpoint mappings and implement the required HTTP methods for each endpoint.

  3. Creating the Service: Create a new Java class to serve as the service layer. Implement the business logic for the API's functionalities. This includes calling the appropriate methods in the repository layer to perform CRUD operations.

  4. Creating the Repository: Create a new Java interface to serve as the repository layer. Extend the appropriate Spring Data JPA interface, such as JpaRepository, to inherit the basic CRUD operations. Define additional methods if needed.

  5. Creating the Model: Create new Java classes to represent the data entities of the API. Annotate the classes with @Entity to indicate that they are persistent entities. Define the attributes and relationships between the entities using annotations like @Id and @JoinColumn.

  6. Implementing CRUD Operations: In the service layer, implement the CRUD operations by calling the corresponding methods in the repository layer. Use the model classes to represent the data and perform the necessary operations like creating, reading, updating, and deleting records.

By following these steps, you can create a basic RESTful API in Spring Boot. Remember to test your API endpoints using tools like Postman or write unit tests using frameworks like JUnit and Mockito.

TEXT/X-JAVA
1class Main {
2  public static void main(String[] args) {
3    // replace with your Java logic here
4    for(int i = 1; i <= 100; i++) {
5      if(i % 3 == 0 && i % 5 == 0) {
6          System.out.println("FizzBuzz");
7      } else if(i % 3 == 0) {
8          System.out.println("Fizz");
9      } else if(i % 5 == 0) {
10          System.out.println("Buzz");
11      } else {
12          System.out.println(i);
13      }
14    }
15  }
16}

Let's test your knowledge. Fill in the missing part by typing it in.

To create a simple API in Spring Boot, we start by setting up a new Spring Boot project and adding the necessary __. We then create the main components of the API, including the controller, service, repository, and model. Finally, we implement the basic CRUD operations using these components.

Write the missing line below.

Handling CRUD Operations in the API

When building an API, one of the essential tasks is to handle CRUD (Create, Read, Update, Delete) operations. In this section, we will learn how to implement these operations in our Spring Boot API.

1. Implementing Create Operation

To implement the create operation, we need to define an endpoint that receives a POST request with the data that needs to be created. In the controller class, we can define a method with the @PostMapping annotation and specify the path for the endpoint. In this method, we can extract the data from the request body and use a service class to create the data in the database.

Here's an example of how the create operation can be implemented:

TEXT/X-JAVA
1class UserController {
2  // ...
3
4  @Autowired
5  private UserService userService;
6
7  @PostMapping("/users")
8  public ResponseEntity<User> createUser(@RequestBody User newUser) {
9      User createdUser = userService.createUser(newUser);
10      return ResponseEntity.ok(createdUser);
11  }
12
13  // ...
14}

In the above example, we define a createUser method that receives a User object as the request body. We then use the userService to create the user and return the created user in the response.

2. Implementing Read Operation

To implement the read operation, we need to define an endpoint that receives a GET request and returns the data from the database. In the controller class, we can define a method with the @GetMapping annotation and specify the path for the endpoint. In this method, we can use a service class to retrieve the data from the database.

Here's an example of how the read operation can be implemented:

TEXT/X-JAVA
1class UserController {
2  // ...
3
4  @Autowired
5  private UserService userService;
6
7  @GetMapping("/users/{id}")
8  public ResponseEntity<User> getUser(@PathVariable Long id) {
9      User user = userService.getUserById(id);
10      if (user != null) {
11          return ResponseEntity.ok(user);
12      } else {
13          return ResponseEntity.notFound().build();
14      }
15  }
16
17  // ...
18}

In the above example, we define a getUser method that retrieves the user with the specified id. If the user is found, we return the user in the response. Otherwise, we return a 404 Not Found response.

3. Implementing Update Operation

To implement the update operation, we need to define an endpoint that receives a PUT request with the updated data. In the controller class, we can define a method with the @PutMapping annotation and specify the path for the endpoint. In this method, we can extract the updated data from the request body and use a service class to update the data in the database.

Here's an example of how the update operation can be implemented:

TEXT/X-JAVA
1class UserController {
2  // ...
3
4  @Autowired
5  private UserService userService;
6
7  @PutMapping("/users/{id}")
8  public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User updatedUser) {
9      User user = userService.getUserById(id);
10      if (user != null) {
11          User updated = userService.updateUser(user, updatedUser);
12          return ResponseEntity.ok(updated);
13      } else {
14          return ResponseEntity.notFound().build();
15      }
16  }
17
18  // ...
19}

In the above example, we define an updateUser method that retrieves the user with the specified id. If the user is found, we update the user with the updated data and return the updated user in the response. Otherwise, we return a 404 Not Found response.

4. Implementing Delete Operation

To implement the delete operation, we need to define an endpoint that receives a DELETE request and deletes the data from the database. In the controller class, we can define a method with the @DeleteMapping annotation and specify the path for the endpoint. In this method, we can use a service class to delete the data from the database.

Here's an example of how the delete operation can be implemented:

TEXT/X-JAVA
1class UserController {
2  // ...
3
4  @Autowired
5  private UserService userService;
6
7  @DeleteMapping("/users/{id}")
8  public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
9      User user = userService.getUserById(id);
10      if (user != null) {
11          userService.deleteUser(user);
12          return ResponseEntity.noContent().build();
13      } else {
14          return ResponseEntity.notFound().build();
15      }
16  }
17
18  // ...
19}

In the above example, we define a deleteUser method that retrieves the user with the specified id. If the user is found, we delete the user from the database and return a 204 No Content response. Otherwise, we return a 404 Not Found response.

By implementing these CRUD operations, we can create robust APIs that allow clients to create, read, update, and delete data effectively. Make sure to handle error cases and return appropriate HTTP responses to provide a good user experience.

JAVA
OUTPUT
:001 > Cmd/Ctrl-Enter to run, Cmd/Ctrl-/ to comment

Try this exercise. Click the correct answer from the options.

Which HTTP method is typically used to implement the create operation in an API?

Click the option that best answers the question.

  • GET
  • POST
  • PUT
  • DELETE

Working with External APIs

When working on a Spring Boot project, it is common to integrate with external APIs to fetch and display data in your application. Integrating with external APIs allows you to leverage existing services and access a wide range of data sources.

Why Work with External APIs?

Working with external APIs provides a lot of benefits for developers:

  • Access to Data: External APIs can provide access to a wide range of data sources such as social media platforms, weather services, financial data providers, and more.
  • Integration: By integrating with external APIs, you can combine different services and functionalities to create more powerful and feature-rich applications.
  • Efficiency: Instead of building everything from scratch, you can leverage existing APIs and services, saving time and effort.

Fetching Data from an External API

To fetch data from an external API in your Spring Boot application, you can use libraries such as RestTemplate or HttpClient. These libraries provide convenient methods for making HTTP requests and handling JSON responses.

Here's an example of how to fetch data from an external API using RestTemplate:

TEXT/X-JAVA
1import org.springframework.web.client.RestTemplate;
2
3public class ExternalAPIService {
4
5    private RestTemplate restTemplate;
6
7    public ExternalAPIService() {
8        this.restTemplate = new RestTemplate();
9    }
10
11    public String fetchDataFromAPI(String apiUrl) {
12        String response = restTemplate.getForObject(apiUrl, String.class);
13        return response;
14    }
15
16}

In the above example, we create an instance of RestTemplate and use its getForObject method to make a GET request to the specified API URL. The response is then returned as a string.

Displaying External API Data in Your Application

Once you have fetched the data from the external API, you can display it in your application. Depending on your requirements, you can use various techniques such as:

  • Populating Model Objects: You can map the external API response to your own model objects and use them to display the data in your application.
  • Rendering Templates: You can render templates with the data retrieved from the external API to display it in a user-friendly format.

The choice of technique depends on the nature of the data and how you want to present it in your application.

Conclusion

Integrating with external APIs is a valuable skill for developers working with Spring Boot. It allows you to tap into a wealth of data and services, enhancing the functionality and capabilities of your applications. By leveraging existing APIs, you can save time and effort and focus on building the core features of your application.

JAVA
OUTPUT
:001 > Cmd/Ctrl-Enter to run, Cmd/Ctrl-/ to comment

Are you sure you're getting this? Click the correct answer from the options.

Which library can be used to make HTTP requests and handle JSON responses in a Spring Boot application?

Click the option that best answers the question.

  • RestTemplate
  • HttpClient
  • OkHttp
  • Retrofit

Authentication and Authorization in APIs

When building APIs in Spring Boot, it is important to implement security measures such as authentication and authorization to protect your application and ensure that only authorized users can access certain resources.

Authentication

Authentication is the process of verifying the identity of a user or client making a request to the API. It ensures that the user is who they claim to be. There are several authentication mechanisms available in Spring Boot, including:

  • Basic Authentication: This mechanism involves sending the credentials (username and password) with each request. The server verifies the credentials before processing the request.
  • Token-based Authentication: In this mechanism, the client obtains a token (e.g., a JSON web token) from the server after successful authentication. The token is then included in subsequent requests for authentication.
  • OAuth2 Authentication: OAuth2 is an industry-standard protocol for authentication and authorization. It allows users to grant limited access to their resources on one site to another site without exposing their credentials.

Here's an example of implementing basic authentication in a Spring Boot API:

TEXT/X-JAVA
1@Configuration
2@EnableWebSecurity
3public class SecurityConfig extends WebSecurityConfigurerAdapter {
4
5    @Override
6    protected void configure(HttpSecurity http) throws Exception {
7        http
8            .authorizeRequests()
9                .antMatchers("/api/public").permitAll()
10                .antMatchers("/api/private").authenticated()
11                .and()
12            .httpBasic();
13    }
14
15    @Override
16    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
17        auth
18            .inMemoryAuthentication()
19                .withUser("user").password("password").roles("USER");
20    }
21
22}

In the above example, the SecurityConfig class extends WebSecurityConfigurerAdapter and overrides the configure methods to define the authentication and authorization rules. The configure(HttpSecurity http) method defines the rules for URL paths, allowing public access to /api/public and requiring authentication for /api/private. The configure(AuthenticationManagerBuilder auth) method provides an in-memory user authentication mechanism for demonstration purposes.

Authorization

Authorization is the process of determining whether a user has the necessary permissions to access a particular resource or perform a specific action. It is usually performed after authentication. In Spring Boot, authorization can be implemented using roles and permissions.

Roles represent specific groups or categories of users, while permissions define what actions a user with a particular role is allowed to perform. A user can have multiple roles and each role can have multiple permissions.

Here's an example of implementing authorization using roles in a Spring Boot API:

TEXT/X-JAVA
1@Configuration
2@EnableWebSecurity
3public class SecurityConfig extends WebSecurityConfigurerAdapter {
4
5    @Override
6    protected void configure(HttpSecurity http) throws Exception {
7        http
8            .authorizeRequests()
9                .antMatchers("/api/public").permitAll()
10                .antMatchers("/api/private").hasRole("USER")
11                .and()
12            .httpBasic();
13    }
14
15    @Override
16    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
17        auth
18            .inMemoryAuthentication()
19                .withUser("user").password("password").roles("USER");
20    }
21
22}

In the above example, the authentication configuration is similar to the previous example. However, the configure(HttpSecurity http) method includes the hasRole("USER") method, which requires the user to have the "USER" role to access the /api/private endpoint.

By implementing authentication and authorization in your Spring Boot API, you can ensure that only authorized users have access to specific resources and actions, increasing the security of your application.

Are you sure you're getting this? Click the correct answer from the options.

What is the purpose of authentication in an API?

Click the option that best answers the question.

  • To verify the identity of the user making a request
  • To determine the permissions of the user making a request
  • To encrypt the data transmitted over the network
  • To handle errors and exceptions that occur in the API

Adding Validation to API Requests

When accepting input data in API requests, it is important to validate the incoming data to ensure its integrity and prevent invalid or unexpected values from being processed. In Spring Boot, you can easily add validation to API requests using annotations and the validation framework provided by Java.

Annotating Request Parameters

One way to validate API requests is to annotate the request parameters or request body objects with validation annotations. These annotations will trigger the validation process automatically before the API method is executed.

For example, let's consider a UserController class with a createUser() method that accepts a User object as the request body:

TEXT/X-JAVA
1public class UserController {
2
3    @PostMapping("/users")
4    public ResponseEntity<String> createUser(@Valid @RequestBody User user) {
5        // Method logic
6    }
7
8}

In the above example, the @Valid annotation is used to indicate that the User object should be validated before the createUser() method is invoked. If any validation errors occur, Spring Boot will automatically handle them and return a proper error response.

Handling Validation Errors

When a validation error occurs in an API request, you can handle the error and return an appropriate response to the client. One way to do this is by using the BindingResult parameter in the API method.

TEXT/X-JAVA
1public class UserController {
2
3    @PostMapping("/users")
4    public ResponseEntity<String> createUser(@Valid @RequestBody User user, BindingResult bindingResult) {
5        if (bindingResult.hasErrors()) {
6            // Handle validation errors
7            return ResponseEntity.badRequest().body("Invalid request data");
8        }
9        // Method logic
10    }
11
12}

In the updated createUser() method, the BindingResult parameter is added to capture the validation result. If any validation errors occur, the hasErrors() method can be used to check if there are any errors, and the appropriate response can be returned.

Custom Validation Annotations

In addition to the built-in validation annotations like @NotNull, @Size, and @Email, you can also create custom validation annotations for more specific validation scenarios. To create a custom validation annotation, you can follow these steps:

  1. Create the annotation interface and specify the target and retention.
  2. Create a validator class that implements the ConstraintValidator interface.
  3. Apply the custom annotation to the target field or method.

Here's an example of creating a custom annotation for validating a phone number:

TEXT/X-JAVA
1@Target({ElementType.FIELD, ElementType.METHOD})
2@Retention(RetentionPolicy.RUNTIME)
3@Constraint(validatedBy = PhoneNumberValidator.class)
4public @interface PhoneNumber {
5    String message() default "Invalid phone number";
6    Class<?>[] groups() default {};
7    Class<? extends Payload>[] payload() default {};
8}

In the example above, PhoneNumber is a custom annotation that is applied to a field or method. The validation logic for the phone number is implemented in the PhoneNumberValidator class.

By adding validation to API requests, you can ensure that only valid and expected data is processed by the API, improving the overall data integrity and reliability of your application.

JAVA
OUTPUT
:001 > Cmd/Ctrl-Enter to run, Cmd/Ctrl-/ to comment

Let's test your knowledge. Fill in the missing part by typing it in.

In Spring Boot, you can easily add validation to API requests using annotations and the validation framework provided by Java. One way to validate API requests is to annotate the request parameters or request body objects with _. These annotations will trigger the validation process automatically before the API method is executed.

Write the missing line below.

Handling Errors and Exceptions in APIs

When working with APIs, it is important to handle errors and exceptions that can occur during the processing of requests. Exception handling helps to ensure that the application can gracefully handle unexpected situations and provide meaningful error responses to clients.

Try-Catch Blocks

One way to handle exceptions in Java is by using try-catch blocks. A try block is used to enclose the code that might throw an exception, and a catch block is used to catch and handle the exception if it occurs.

For example, let's consider a method divide() that performs division:

SNIPPET
1public static int divide(int numerator, int denominator) {
2  return numerator / denominator;
3}

If we call the divide() method with a denominator of zero, it will throw an ArithmeticException:

SNIPPET
1int result = divide(10, 0);

To handle this exception, we can wrap the method call in a try-catch block:

SNIPPET
1try {
2    int result = divide(10, 0);
3    System.out.println("Result: " + result);
4} catch (ArithmeticException e) {
5    System.out.println("Error: Cannot divide by zero");
6}

In the above example, if the exception occurs in the try block, it will be caught by the catch block, and the appropriate error message will be printed.

Exception Types

Java provides several built-in exception types that cover a wide range of error scenarios. Some common exception types include:

  • ArithmeticException: Thrown when an arithmetic operation (such as division) results in an error
  • NullPointerException: Thrown when a null reference is used
  • IllegalArgumentException: Thrown when an invalid argument is passed to a method
  • IOException: Thrown when an input/output operation fails

It is important to choose the right exception type that accurately represents the error scenario. Additionally, you can also create custom exception classes by extending the Exception class.

Exception handling is an essential part of API development as it allows for robust error handling and provides helpful feedback to clients when errors occur during API requests.

JAVA
OUTPUT
:001 > Cmd/Ctrl-Enter to run, Cmd/Ctrl-/ to comment

Try this exercise. Click the correct answer from the options.

Which of the following is true about exception handling in Java?

Click the option that best answers the question.

  • Exceptions should always be caught and handled within the same method where they occur
  • The try block is used to catch exceptions and the catch block is used to handle them
  • Unchecked exceptions are always caught at compile-time
  • Exceptions provide a way to handle expected errors and abnormal situations

Implementing Pagination and Sorting in APIs

When working with APIs, it is common to deal with large datasets. Retrieving and displaying all the data in a single response might not be practical and can impact performance. In such cases, implementing pagination and sorting functionality in APIs can help improve efficiency and provide a better user experience.

Pagination

Pagination is the process of dividing a large dataset into smaller, more manageable subsets called pages. Each page contains a specified number of items, and the API client can request different pages to retrieve the desired data.

To implement pagination in API endpoints, we need to consider the following:

  • Page number: The current page being requested.
  • Page size: The number of items to include in each page.
  • Total items: The total number of items in the dataset.

For example, let's say we have a list of users stored in a database. To retrieve the first page of users with 10 users per page, we can use a PageRequest object provided by Spring Boot:

TEXT/X-JAVA
1int pageNumber = 1;
2int pageSize = 10;
3List<User> users = userRepository.findAll(PageRequest.of(pageNumber - 1, pageSize)).getContent();

In the above code, we specify the page number (1 in this case) and the page size (10 in this case) to limit the result set. The PageRequest.of() method creates a PageRequest object, and the findAll() method returns a Page object. We can call getContent() on the Page object to retrieve the list of users for the requested page.

Sorting

Sorting allows us to arrange the data in a specific order based on one or more fields. In API endpoints, sorting can be useful when the client wants to retrieve the data in a particular order.

To implement sorting in an API endpoint, we can use the Sort class provided by Spring Boot:

TEXT/X-JAVA
1List<User> sortedUsers = userRepository.findAll(Sort.by(Sort.Direction.ASC, "name"));

In the above code, we specify the sorting direction (ascending in this case) and the field to sort by (name in this case) using the Sort.by() method. The findAll() method takes a Sort object as an argument and returns the sorted list of users.

By combining pagination and sorting, we can efficiently retrieve and sort large datasets in APIs, providing a smoother experience for the API clients.

JAVA
OUTPUT
:001 > Cmd/Ctrl-Enter to run, Cmd/Ctrl-/ to comment

Pagination and sorting functionality in APIs can help improve efficiency and provide a better user experience.

Solution: true

Testing APIs with JUnit and Mockito

When developing APIs in Spring Boot, it is essential to thoroughly test the functionality of the API to ensure that it behaves as expected and handles various scenarios correctly. JUnit and Mockito are popular frameworks for writing unit tests in Java.

JUnit is a testing framework that provides annotations and assert methods to write and run tests. It allows you to define test methods, set up test data, and assert expected outcomes. Mockito, on the other hand, is a mocking framework that allows you to create mock objects of dependencies for unit testing.

Let's take a look at an example of how to write a unit test for an API using JUnit and Mockito:

TEXT/X-JAVA
1// Mock service
2MyService myService = Mockito.mock(MyService.class);
3
4// Set up mock response
5Mockito.when(myService.getData()).thenReturn("Test Data");
6
7// Create instance of controller
8MyController myController = new MyController(myService);
9
10// Perform test
11String result = myController.getData();
12
13// Verify the result
14Assert.assertEquals("Test Data", result);
JAVA
OUTPUT
:001 > Cmd/Ctrl-Enter to run, Cmd/Ctrl-/ to comment

Let's test your knowledge. Fill in the missing part by typing it in.

Unit tests for APIs are written using _ and _.

Write the missing line below.

Deploying the API to a Server

Once you have developed your API in Spring Boot, the next step is to deploy it to a server for production use. Deploying an API involves making it accessible to clients and ensuring its availability and scalability.

There are multiple options available for deploying Spring Boot applications:

  1. Self-Contained Deployment: You can package your API as a self-contained deployable artifact, such as a JAR or WAR file. This artifact can be run as a standalone application on a server or a cloud platform.

  2. Containerized Deployment: Another popular option is to containerize your API using tools like Docker. Containerization allows you to package your API along with its dependencies and run it in a lightweight, portable container. This approach offers easier deployment and scalability.

  3. Cloud Deployment: Cloud platforms such as Amazon Web Services (AWS) and Microsoft Azure provide cloud-based infrastructure for deploying and managing applications. You can leverage these platforms to deploy your API in a scalable and cost-effective manner.

  4. Serverless Deployment: If your API has sporadic usage patterns or requires automatic scaling, you can consider serverless deployment options like AWS Lambda or Google Cloud Functions. With serverless architectures, you only pay for the actual usage of your API.

Choose the deployment option that best suits your application's requirements and the infrastructure available to you. It is also important to consider factors such as scalability, security, and cost when selecting a deployment strategy.

Let's take a look at a sample Java code snippet that demonstrates a simple deployment logic:

SNIPPET
1{{code}}

This code snippet demonstrates a simple deployment logic placeholder. In a real-world scenario, you would replace it with the appropriate deployment commands and configurations based on your chosen deployment option.

Remember to test your deployed API thoroughly and monitor its performance in the production environment to ensure smooth operation and optimal user experience.

JAVA
OUTPUT
:001 > Cmd/Ctrl-Enter to run, Cmd/Ctrl-/ to comment

Try this exercise. Is this statement true or false?

Docker can be used for containerized deployment of Spring Boot APIs.

Press true if you believe the statement is correct, or false otherwise.

Generating complete for this lesson!