0% found this document useful (0 votes)
32 views55 pages

Rest Unit 1 Cls Notes

Uploaded by

oopsitsmysteria
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views55 pages

Rest Unit 1 Cls Notes

Uploaded by

oopsitsmysteria
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 55

22IT910-REST APPLICATION DEVELOPMENT USING

SPRING BOOT AND JPA

UNIT-1 INTRODUCTION TO REST API


RESTful APIs – overview about data exchange between client and server - separating
concerns between handling HTTP requests and executing business logic - retrieving
server resources via HTTP requests - injection of property values - self-contained
application - serialization and deserialization – JSON properties - managing data
access

Building REST ful services

What is RESTful API?


RESTful API is an interface that two computer systems use to exchange information securely
over the internet. Most business applications have to communicate with other internal and
third-party applications to perform various tasks.

For example, to generate monthly payslips, your internal accounts system has to share data with
your customer's banking system to automate invoicing and communicate with an internal
timesheet application. RESTful APIs support this information exchange because they follow
secure, reliable, and efficient software communication standards.

What is an API?
An application programming interface (API) defines the rules that you must follow to
communicate with other software systems. Developers expose or create APIs so that other
applications can communicate with their applications programmatically.

For example, the timesheet application exposes an API that asks for an employee's full name and
a range of dates. When it receives this information, it internally processes the employee's
timesheet and returns the number of hours worked in that date range.
Let's say you're in a restaurant. You can't (or shouldn't) walk into the kitchen and start cooking
yourself. Most likely, you place your order via a server, who delivers it to the kitchen staff to
prepare it. In this scenario, the kitchen staff is the backend, the menu is the database, and the
waiter is the API. You choose from the menu (database), and the waiter (API) sends the info to
the kitchen (back end).

The kitchen will prepare a meal and, before reaching your hands, it will go through the waiter
again. In sum, an API is a ruleset specifying backend interactions. APIs allow selecting specific
input from data and receiving a final-user-focused answer.

You can think of a web API as a gateway between clients and resources on the web.

Clients
Clients are users who want to access information from the web. The client can be a person or a
software system that uses the API. For example, developers can write programs that access
weather data from a weather system. Or you can access the same data from your browser when
you visit the weather website directly.

Resources

Resources are the information that different applications provide to their clients. Resources can
be images, videos, text, numbers, or any type of data. The machine that gives the resource to the
client is also called the server. Organizations use APIs to share resources and provide web
services while maintaining security, control, and authentication. In addition, APIs help them to
determine which clients get access to specific internal resources.

What is REST?
Representational State Transfer (REST) is a software architecture that imposes conditions on
how an API should work. REST was initially created as a guideline to manage communication
on a complex network like the internet. You can use REST-based architecture to support
high-performing and reliable communication at scale. You can easily implement and modify it,
bringing visibility and cross-platform portability to any API system.

API developers can design APIs using several different architectures. APIs that follow the REST
architectural style are called REST APIs. Web services that implement REST architecture are
called RESTful web services. The term RESTful API generally refers to RESTful web APIs.
However, you can use the terms REST API and RESTful API interchangeably.

REST is not a protocol, but an architectural principle for managing state information. It's mainly
used in web applications. REST was introduced by Roy Fielding to overcome implementation
difficulties in SOAP. Roy's doctoral dissertation made for an easy way to retrieve data, regardless
of the platform used

Separation of Client and Server


In the REST architectural style, the implementation of the client and the implementation of the
server can be done independently without each knowing about the other. This means that the
code on the client side can be changed at any time without affecting the operation of the server,
and the code on the server side can be changed without affecting the operation of the client.
As long as each side knows what format of messages to send to the other, they can be kept
modular and separate. Separating the user interface concerns from the data storage concerns, we
improve the flexibility of the interface across platforms and improve scalability by simplifying
the server components. Additionally, the separation allows each component the ability to evolve
independently.
By using a REST interface, different clients hit the same REST endpoints, perform the same
actions, and receive the same responses.
.

The following are some of the principles of the REST architectural style:
Uniform interface

In REST principles, all resources are identified by the Uniform Resource Identifier (URI). HTTP
REST resources are represented in some media types, such as XML, JSON, and RDF. Also,
RESTful resources are self-descriptive, which means enough information is given to describe
how to process the request. In another REST principle, the clients interact with servers through
hypermedia, which is dynamically provided by the servers. Other than endpoints, clients don't
need to know how to interact with RESTful services. This principle is referred to as
Hypermedia as the Engine of Application State (HATEOAS)

The uniform interface is fundamental to the design of any RESTful web service. It indicates that
the server transfers information in a standard format. The formatted resource is called a
representation in REST. This format can be different from the internal representation of the
resource on the server application. For example, the server can store data as text but send it in an
HTML representation format.

Uniform interface imposes four architectural constraints:

1.​ Requests should identify resources. They do so by using a uniform resource identifier.
2.​ Clients have enough information in the resource representation to modify or delete the
resource if they want to. The server meets this condition by sending metadata that
describes the resource further.
3.​ Clients receive information about how to process the representation further. The server
achieves this by sending self-descriptive messages that contain metadata about how the
client can best use them.
4.​ Clients receive information about all other related resources they need to complete a
task. The server achieves this by sending hyperlinks in the representation so that clients
can dynamically discover more resources.

Statelessness

In REST architecture, statelessness refers to a communication method in which the server


completes every client request independently of all previous requests. Clients can request
resources in any order, and every request is stateless or isolated from other requests. This REST
API design constraint implies that the server can completely understand and fulfill the request
every time.

Layered system

In a layered system architecture, the client can connect to other authorized intermediaries
between the client and server, and it will still receive responses from the server. Servers can also
pass on requests to other servers. You can design your RESTful web service to run on several
servers with multiple layers such as security, application, and business logic, working together to
fulfill client requests. These layers remain invisible to the client.

Cacheability

RESTful web services support caching, which is the process of storing some responses on the
client or on an intermediary to improve server response time. For example, suppose that you visit
a website that has common header and footer images on every page. Every time you visit a new
website page, the server must resend the same images. To avoid this, the client caches or stores
these images after the first response and then uses the images directly from the cache. RESTful
web services control caching by using API responses that define themselves as cacheable or non
cacheable.

Code on demand

In REST architectural style, servers can temporarily extend or customize client functionality by
transferring software programming code to the client. For example, when you fill a registration
form on any website, your browser immediately highlights any mistakes you make, such as
incorrect phone numbers. It can do this because of the code sent by the server.

What is a Resource?

The key abstraction of information in REST is a resource. Any information that we can name can
be a resource. For example, a REST resource can be a document or image, a temporal service, a
collection of other resources, or a non-virtual object (e.g., a person).

The state of the resource, at any particular time, is known as the resource representation. The
resource representations consist of:

●​ the data
●​ the metadata describing the data
●​ and the hypermedia links that can help the clients transition to the next desired
state.

A REST API consists of an assembly of interlinked resources. This set of resources is known as
the REST API’s resource model.

Resource Identifiers

REST uses resource identifiers to identify each resource involved in the interactions between the
client and the server components.

What are the benefits of RESTful APIs?


RESTful APIs include the following benefits:

Scalability

Systems that implement REST APIs can scale efficiently because REST optimizes client-server
interactions. Statelessness removes server load because the server does not have to retain past
client request information. Well-managed caching partially or completely eliminates some
client-server interactions. All these features support scalability without causing communication
bottlenecks that reduce performance.

Flexibility

RESTful web services support total client-server separation. They simplify and decouple various
server components so that each part can evolve independently. Platform or technology changes at
the server application do not affect the client application. The ability to layer application
functions increases flexibility even further. For example, developers can make changes to the
database layer without rewriting the application logic.

Independence

REST APIs are independent of the technology used. You can write both client and server
applications in various programming languages without affecting the API design. You can also
change the underlying technology on either side without affecting the communication.

How do RESTful APIs work?


The basic function of a RESTful API is the same as browsing the internet. The client contacts the
server by using the API when it requires a resource. API developers explain how the client
should use the REST API in the server application API documentation. These are the general
steps for any REST API call:

1.​ The client sends a request to the server. The client follows the API documentation to
format the request in a way that the server understands.
2.​ The server authenticates the client and confirms that the client has the right to make that
request.
3.​ The server receives the request and processes it internally.
4.​ The server returns a response to the client. The response contains information that tells
the client whether the request was successful. The response also includes any
information that the client requested.

The REST API request and response details vary slightly depending on how the API developers
design the API.
Building a RESTful API

At a high level, here are the steps involved in building a RESTful API:

1. Identify Resources—Central to REST are resources. We start modeling different resources that
are of interest to our consumers. Often, these resources can be the application’s domain or
entities. However, a one-to-one mapping is not always required.

2. Identify Endpoints—The next step is to design URIs that map resources to endpoints. In
Chapter 4, we will look at best practices for designing and naming endpoints.

3. Identify Actions—Identify the HTTP methods that can be used to perform operations on the
resources.

4. Identify Responses—Identify the supported resource representation for the request and
response along with the right status codes to be returned.
Overview of data exchange between client and server
Data exchange between a client and server is a fundamental aspect of web development,
allowing clients (such as web browsers or mobile apps) to communicate with servers to request
and manipulate data. Here’s an overview of the key components and processes involved in data
exchange between a client and server:

1. Resource Identification :
REST APIs are resource-based, meaning that each resource (e.g., object, data, service) is
identified by a unique URL (Uniform Resource Locator). Clients identify the specific resource
they want to interact with by specifying the corresponding URL.

2. HTTP Protocol

The Hypertext Transfer Protocol (HTTP) is the foundation of data exchange on the web. HTTP
defines how messages are formatted and transmitted, and what actions servers and clients should
take in response to various commands.

3. Requests and Responses

●​ HTTP Request: Sent by the client to the server to request data or perform an action. It
includes:
○​ Request Line: Contains the HTTP method (GET, POST, etc.), the resource URL,
and the HTTP version.
○​ Headers: Provide metadata about the request, such as content type, authorization,
and user agent.
○​ Body: Optional and typically used with POST, PUT, and PATCH methods to send
data to the server.
●​ HTTP Response: Sent by the server back to the client, containing the requested data or
the result of the action. It includes:
○​ Status Line: Contains the HTTP version, status code (200, 404, etc.), and a
reason phrase.
○​ Headers: Provide metadata about the response, such as content type and content
length.
○​ Body: Contains the data requested by the client or the result of the action
performed.

4. Data Formats

Data exchanged between client and server can be in various formats, with JSON (JavaScript
Object Notation) and XML (Extensible Markup Language) being the most common.
●​ JSON: Lightweight, easy to read and write, and widely used in web APIs.

{
"name": "John Doe",
"email": "[email protected]"
}
XML: More verbose than JSON but still widely used, especially in enterprise systems.
<user>
<name>John Doe</name>
<email>[email protected]</email>
</user>

5. RESTful APIs

Representational State Transfer (REST) is an architectural style for designing networked


applications. RESTful APIs use standard HTTP methods and status codes to facilitate data
exchange.

●​ HTTP Methods:
○​ GET: Retrieve data.
○​ POST: Create new data.
○​ PUT: Update existing data.
○​ DELETE: Remove data.
○​ PATCH: Partially update data.
●​ Status Codes:
○​ 200 OK: Request succeeded.
○​ 201 Created: Resource created successfully.
○​ 400 Bad Request: Client error.
○​ 404 Not Found: Resource not found.
○​ 500 Internal Server Error: Server error.
○​ 204 No Content
○​ 403 (FORBIDDEN)

For each HTTP verb, there are expected status codes a server should return upon success:

●​ GET — return 200 (OK)


●​ POST — return 201 (CREATED)
●​ PUT — return 200 (OK)
●​ DELETE — return 204 (NO CONTENT) If the operation fails, return the most specific
status code possible corresponding to the problem that was encountered.
Summary

●​ HTTP Protocol: Foundation for client-server communication.


●​ Requests and Responses: Core elements of data exchange.
●​ Data Formats: JSON and XML are commonly used.
●​ RESTful APIs: Use standard HTTP methods and status codes.

Separating concerns between handling HTTP requests and executing business logic

Separating concerns between handling HTTP requests and executing business logic is essential
for creating maintainable and scalable applications. In the context of a Spring Boot application,
this separation can be achieved using a layered architecture.

Role of business logic in API development

Business logic defines how data is processed, manipulated, and transformed in response to user
interactions. In API development, it determines what data is collected from users, how it's stored,
and the processes it undergoes before being delivered or updated. Business logic is the engine
that powers the functionality of APIs.

●​ Business logic is the set of rules that govern data creation and changes, specific to
industry and business.
●​ Business logic plays a crucial role in digital transformation, determining how technology
integrates with business infrastructure.
●​ Understanding our data's structure and its role in front-end applications is fundamental in
implementing any transformation initiative.
●​ Scaling business logic with APIs involves horizontal scaling (load
balancing,microservices) and vertical scaling (rate limiting, optimized code).
●​ API generation automates API creation, simplifying development and allowing
developers to focus on refining core business logic, ultimately enhancing application
functionality.

Scaling Business Logic with APIs


As businesses grow and experience increased user demands, the need to scale their infrastructure
to handle higher loads and data processing requirements becomes paramount. Scaling business
logic effectively is a critical aspect of ensuring that applications remain responsive and reliable.

Methods for scaling business logic both Horizontally and Vertically using APIs.

1.Horizontal Scaling

Horizontal scaling involves adding more resources, such as servers or Containers,to distribute the
workload evenly across multiple instances.

Load Balancing: Implementing an API gateway or load balancer can evenly distribute incoming
requests across multiple instances of your application. This ensures that no single server becomes
a bottleneck and helps maintain consistent response times.

Microservices Architecture: Organize your business logic into microservices, each


encapsulating a specific function or feature. APIs act as the communication layer between these
microservices, allowing you to scale individual components independently based on their usage
patterns.

Elastic Scaling: Utilize cloud-based infrastructure that allows you to dynamically add or remove
instances based on traffic fluctuations. Cloud providers offer services like AWS Auto Scaling or
Kubernetes auto-scaling that can automatically adjust the number of API servers in response to
demand.

Caching: Implement caching mechanisms at the API level to reduce the load on backend
systems. Cached responses can be served quickly, reducing the need to recompute or retrieve
data for every request.

2.Vertical Scaling

Vertical scaling involves increasing the capacity of a single server or instance to handle more
significant workloads.

API Rate Limiting: Implement rate limiting on API endpoints to control the number of requests
a single client can make within a specific time frame. This prevents individual clients from
overwhelming the server and allows for fair resource allocation.
Optimized Code and Algorithms: Continuously optimize your business logic code and
algorithms to make the most efficient use of available resources. Fine-tuning the performance of
your API endpoints can significantly enhance vertical scalability.

Vertical Scaling Tools: If using virtual machines or dedicated servers, consider using tools and
technologies that enable you to increase CPU, RAM, or other resources as needed. API
endpoints can be fine-tuned to take advantage of the added capacity.

Database Scaling: When business logic heavily relies on database operations,vertical scaling of
the database can also be essential. APIs can help manage connections to the database and
distribute queries efficiently.

Content Delivery Networks (CDNs): Offload static content and assets to CDNs,reducing the
load on your API servers. CDNs can serve cached content from edge locations closer to users,
improving response times

The primary layers typically include the Controller layer, Service layer, and Repository layer.
Here's how each layer functions:
1. Controller Layer

The Controller layer handles HTTP requests and responses. It acts as an intermediary between
the client and the service layer. Controllers are responsible for:

●​ Mapping HTTP requests to specific handler methods.


●​ Validating input data.
●​ Returning appropriate HTTP responses.

Example:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/users")
public class UserController {

@Autowired
private UserService userService;

@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
User createdUser = userService.saveUser(user);
return new ResponseEntity<>(createdUser, HttpStatus.CREATED);
}

@GetMapping
public ResponseEntity<List<User>> getAllUsers() {
List<User> users = userService.getAllUsers();
return new ResponseEntity<>(users, HttpStatus.OK);
}

@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = userService.getUserById(id);
return user != null ? new ResponseEntity<>(user, HttpStatus.OK) : new
ResponseEntity<>(HttpStatus.NOT_FOUND);
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
}

2. Service Layer

The Service layer contains business logic and interacts with the Repository layer to fetch or
manipulate data. This layer ensures that the business rules are applied and provides a clear
separation of concerns.

Example:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {

@Autowired
private UserRepository userRepository;

public User saveUser(User user) {


// Business logic (e.g., validation, transformation) can be added here
return userRepository.save(user);
}

public List<User> getAllUsers() {


return userRepository.findAll();
}

public User getUserById(Long id) {


return userRepository.findById(id).orElse(null);
}
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
}

3. Repository Layer

The Repository layer interacts directly with the database. It contains methods for CRUD
operations and custom queries. This layer abstracts the data access logic and provides a cleaner
way to interact with the database.

Example:

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {


// Custom query methods can be defined here if needed
}

Benefits of Separating Concerns

1.​ Maintainability: Each layer has a distinct responsibility, making the codebase easier to
understand and maintain.
2.​ Testability: Individual layers can be tested independently. For example, unit tests can be
written for the Service layer without involving the Controller or Repository layers.
3.​ Reusability: Business logic in the Service layer can be reused across different controllers
or applications.
4.​ Scalability: The application can be scaled more easily by optimizing individual layers.
5.​ Flexibility: Changes in one layer (e.g., switching from a relational database to a NoSQL
database) do not affect other layers significantly.

Summary

●​ Controller Layer: Handles HTTP requests and responses, performs input validation, and
delegates business logic to the Service layer.
●​ Service Layer: Contains business logic, interacts with the Repository layer, and ensures
that business rules are applied.
●​ Repository Layer: Directly interacts with the database, performs CRUD operations, and
abstracts data access logic.
Retrieving server resources via HTTP requests

Retrieving server resources via HTTP requests involves using HTTP methods to interact with the
server and fetch data. The most common method for retrieving resources is the GET request, but
other methods like POST, PUT, DELETE, etc., can also be used depending on the specific
requirements.

Retrieving server resources via HTTP requests involves using HTTP methods to interact with
server endpoints. A typical Spring Boot application is structured with a Controller layer to
handle HTTP requests, a Service layer to execute business logic, and a Repository layer to
interact with the database. This separation of concerns leads to a clean and maintainable
architecture, making it easier to develop, test, and scale the application.

Example Program : Write any one

The envelope format

The first piece of information that is relevant to any operation is whether it was successful. We
can encapsulate that information with a status. Secondly, most requests will return data.
Therefore, a field in our envelope could provide generic access to the response payload.

The following format will form the base of any responses returned by the API:

{ "status": "OK", "data": {…} }

With this response format, we ensured that client developers will have a consistent way to check
if a request was successful and access the payload

What does the RESTful API client request contain?


RESTful APIs require requests to contain the following main components:

Unique resource identifier

The server identifies each resource with unique resource identifiers. For REST services, the
server typically performs resource identification by using a Uniform Resource Locator (URL).
The URL specifies the path to the resource. A URL is similar to the website address that you
enter into your browser to visit any webpage. The URL is also called the request endpoint and
clearly specifies to the server what the client requires.

Method

Developers often implement RESTful APIs by using the Hypertext Transfer Protocol (HTTP).
An HTTP method tells the server what it needs to do to the resource. The following are four
common HTTP methods:

GET

Clients use GET to access resources that are located at the specified URL on the server. They can
cache GET requests and send parameters in the RESTful API request to instruct the server to
filter data before sending.

●​ GET: Request for all Students.

GET:/api/students

POST

Clients use POST to send data to the server. They include the data representation with the
request. Sending the same POST request multiple times has the side effect of creating the same
resource multiple times.

●​ POST: Request for Posting/Creating/Inserting Data

POST:/api/students
{“name”:”Raj”}

PUT

Clients use PUT to update existing resources on the server. Unlike POST, sending the same PUT
request multiple times in a RESTful web service gives the same result.

●​ PUT or PATCH: Request for Updating Data at id=1

PUT or PATCH:/api/students/1

{“name”:”Raj”}

DELETE

Clients use the DELETE request to remove the resource. A DELETE request can change the
server state. However, if the user does not have appropriate authentication, the request fails.

●​ DELETE: Request for Deleting Data of id=1

DELETE:/api/students/1

Endpoint: The endpoint shows where the resource is located. It typically includes a Uniform
Resource Identifier (URI). If the resource is accessed through the internet, the URI can be a URL
that provides a web address for the resource.

HTTP headers
Request headers are the metadata exchanged between the client and server. For instance, the
request header indicates the format of the request and response, provides information about
request status, and so on.

Data

REST API requests might include data for the POST, PUT, and other HTTP methods to work
successfully.

Parameters

RESTful API requests can include parameters that give the server more details about what needs
to be done. The following are some different types of parameters:

●​ Path parameters that specify URL details.


●​ Query parameters that request more information about the resource.
●​ Cookie parameters that authenticate clients quickly.

What are RESTful API authentication methods?


A RESTful web service must authenticate requests before it can send a response. Authentication
is the process of verifying an identity. For example, you can prove your identity by showing an
ID card or driver's license. Similarly, RESTful service clients must prove their identity to the
server to establish trust.

RESTful API has four common authentication methods:

HTTP authentication
HTTP defines some authentication schemes that you can use directly when you are
implementing REST API. The following are two of these schemes:

Basic authentication

In basic authentication, the client sends the user name and password in the request header. It
encodes them with base64, which is an encoding technique that converts the pair into a set of 64
characters for safe transmission.

Bearer authentication

The term bearer authentication refers to the process of giving access control to the token bearer.
The bearer token is typically an encrypted string of characters that the server generates in
response to a login request. The client sends the token in the request headers to access resources.

API keys

API keys are another option for REST API authentication. In this approach, the server assigns a
unique generated value to a first-time client. Whenever the client tries to access resources, it uses
the unique API key to verify itself. API keys are less secure because the client has to transmit the
key, which makes it vulnerable to network theft.

OAuth

OAuth combines passwords and tokens for highly secure login access to any system. The server
first requests a password and then asks for an additional token to complete the authorization
process. It can check the token at any time and also over time with a specific scope and
longevity.
What does the RESTful API server response contain?
REST principles require the server response to contain the following main components:

Status line

The status line contains a three-digit status code that communicates request success or failure.
For instance, 2XX codes indicate success, but 4XX and 5XX codes indicate errors. 3XX codes
indicate URL redirection.

The following are some common status codes:

●​ 200: Generic success response


●​ 201: POST method success response
●​ 400: Incorrect request that the server cannot process or BAD REQUEST(The request
body does not meet the API specification. It does not contain enough details or contains
validation errors. )
●​ 401: UNAUTHORIZED
●​ 403: FORBIDDEN
●​ 404: Resource not found
●​ 405:METHOD NOT ALLOWED
●​ 500:Internal server error

Message body

The response body contains the resource representation. The server selects an appropriate
representation format based on what the request headers contain. Clients can request information
in XML or JSON formats, which define how the data is written in plain text. For example, if the
client requests the name and age of a person named John, the server returns a JSON
representation as follows:

'{"name":"John", "age":30}'
Headers

The response also contains headers or metadata about the response. They give more context
about the response and include information such as the server, encoding, date, and content type.

What are some real-world applications of RESTful APIs?


RESTful APIs are commonly used in web and mobile applications to retrieve or modify
resources and data on remote systems. Some examples include:
●​ Social media sites like Twitter, Facebook use REST APIs to integrate with third-party
applications and allow posting updates.
●​ Ridesharing apps like Uber and Lyft use REST APIs to coordinate cars, obtain maps,
fares and location data.
●​ Video, music streaming through Netflix, Spotify use REST APIs to get info on media
files from servers.
●​ Banking apps utilize REST APIs to retrieve your account data and initiate transactions
with remote servers.
●​ IoT apps interface with sensors and devices via REST APIs to monitor them and send
commands.

Imperative and Reactive programming


Let's see a small comparison between Imperative programming and Reactive programming: x =
y + z.The value of x would be assigned at the time of the expression x = y + z. The value of x
will never change after this expression.
But in some cases, we might need the value of x to be updated, corresponding to the change in y
or z. Reactive programming is the perfect solution for this scenario. In Reactive programming,
the value of x would automatically be updated, corresponding to the change in y or z.
Spreadsheet reference cells are the best example of Reactive programming. If a cell value
changes, the referred cell value will be updated automatically. Another example can be found in
a Model-View-Controller architecture, Reactive programming can automatically update the
View, which is attached to the Model.
Reactive programming follows the Observer pattern to manipulate and transform the stream of
data where the Publisher (observable) emits the items based on the Subscriber's need. As the
Publisher emits the item, the Subscriber consumes those emitted items from the Publisher.
Unlike the iterator pulling the items, here, the Publisher is pushing the items to the Subscriber.
Spring Framework 5.0 added Reactive features built into it, including the tools for HTTP servers
and clients. Spring users find annotations and controllers handy when they deal with HTTP
requests, especially dispatching Reactive requests and back pressure concerns to the framework.

Spring Boot Annotations


Spring Boot Annotations is a form of metadata that provides data about a program. In other
words, annotations are used to provide supplemental information about a program. It is not a
part of the application that we develop. It does not have a direct effect on the operation of the
code they annotate. It does not change the action of the compiled program.

@Component: It is a class-level annotation. It is used to mark a Java class as a bean. A Java


class annotated with @Component is found during the classpath. The Spring Framework pick it
up and configure it in the application context as a Spring Bean.

Example

1.​ @Component
2.​ public class Student
3.​ {
4.​ .......
5.​ }

@Controller: The @Controller is a class-level annotation. It is a specialization of


@Component. It marks a class as a web request handler. It is often used to serve web pages. By
default, it returns a string that indicates which route to redirect. It is mostly used with
@RequestMapping annotation.
1.​ @Controller
2.​ @RequestMapping("books")
3.​ public class BooksController
4.​ {
5.​ @RequestMapping(value = "/{name}", method = RequestMethod.GET)
6.​ public Employee getBooksByName()
7.​ {
8.​ return booksTemplate;
9.​ }
10.​}

@Service: It is also used at class level. It tells the Spring that class contains the business logic.
package com.javatpoint;

@Service

1.​ public class TestService


2.​ {
3.​ public void service1()
4.​ {
5.​ //business code
6.​ }
7.​ }

@Repository: It is a class-level annotation. The repository is a DAOs (Data Access Object) that
access the database directly. The repository does all the operations related to the database.

package com.javatpoint;

@Repository

public class TestRepository

public void delete()

//persistence code

}
@EnableAutoConfiguration: It auto-configures the bean that is present in the classpath
and configures it to run the methods. The use of this annotation is reduced in Spring Boot
1.2.0 release because developers provided an alternative of the annotation, i.e.
@SpringBootApplication.

@SpringBootApplication: It is a combination of three annotations


@EnableAutoConfiguration, @ComponentScan, and @Configuration.

Spring MVC and REST Annotations

○​ @RequestMapping: It is used to map the web requests. It has many optional elements
like consumes, header, method, name, params, path, produces, and value. We use it
with the class as well as the method.

○​ @GetMapping: It maps the HTTP GET requests on the specific handler method. It is
used to create a web service endpoint that fetches It is used instead of using:
@RequestMapping(method = RequestMethod.GET)

○​ @PostMapping: It maps the HTTP POST requests on the specific handler method. It is
used to create a web service endpoint that creates It is used instead of using:
@RequestMapping(method = RequestMethod.POST)

○​ @PutMapping: It maps the HTTP PUT requests on the specific handler method. It is
used to create a web service endpoint that creates or updates It is used instead of using:
@RequestMapping(method = RequestMethod.PUT)

○​ @DeleteMapping: It maps the HTTP DELETE requests on the specific handler


method. It is used to create a web service endpoint that deletes a resource. It is used
instead of using: @RequestMapping(method = RequestMethod.DELETE)

○​ @PatchMapping: It maps the HTTP PATCH requests on the specific handler method.
It is used instead of using: @RequestMapping(method = RequestMethod.PATCH)
○​ @RequestBody: It is used to bind HTTP request with an object in a method parameter.
Internally it uses HTTP MessageConverters to convert the body of the request. When
we annotate a method parameter with @RequestBody, the Spring framework binds the
incoming HTTP request body to that parameter.

○​ @ResponseBody: It binds the method return value to the response body. It tells the
Spring Boot Framework to serialize a return an object into JSON and XML format.

○​ @PathVariable: It is used to extract the values from the URI. It is most suitable for the
RESTful web service, where the URL contains a path variable. We can define multiple
@PathVariable in a method.

○​ @RequestParam: It is used to extract the query parameters form the URL. It is also
known as a query parameter. It is most suitable for web applications. It can specify
default values if the query parameter is not present in the URL.

○​ @RequestHeader: It is used to get the details about the HTTP request headers. We use
this annotation as a method parameter. The optional elements of the annotation are
name, required, value, defaultValue. For each detail in the header, we should specify
separate annotations. We can use it multiple time in a method

○​ @RestController: It can be considered as a combination of @Controller and


@ResponseBody annotations. The @RestController annotation is itself annotated with
the @ResponseBody annotation. It eliminates the need for annotating each method with
@ResponseBody.

○​ @RequestAttribute: It binds a method parameter to request attribute. It provides


convenient access to the request attributes from a controller method. With the help of
@RequestAttribute annotation, we can access objects that are populated on the
server-side.

INJECTION OF PROPERTY VALUES


In Spring Boot, injection of property values can be managed in various ways, such as using
@Value annotation, @ConfigurationProperties annotation, or by injecting the Environment
object. Here’s a brief overview of each approach:
Example:

application.properties

app.name=MyApp
app.version=1.0.0

ExampleService.java
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class ExampleService {

@Value("${app.name}")
private String appName;

@Value("${app.version}")
private String appVersion;

public void printAppInfo() {


System.out.println("App Name: " + appName);
System.out.println("App Version: " + appVersion);
}
}

2. Using @ConfigurationProperties Annotation

This approach is used to bind all properties with a common prefix to a JavaBean-style POJO.

Example:

application.properties

app.name=MyApp
app.version=1.0.0

AppProperties.java

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {

private String name;


private String version;

// getters and setters

public String getName() {


return name;
}

public void setName(String name) {


this.name = name;
}

public String getVersion() {


return version;
}

public void setVersion(String version) {


this.version = version;
}
}

ExampleService.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ExampleService {

private final AppProperties appProperties;

@Autowired
public ExampleService(AppProperties appProperties) {
this.appProperties = appProperties;
}

public void printAppInfo() {


System.out.println("App Name: " + appProperties.getName());
System.out.println("App Version: " + appProperties.getVersion());
}
}

3. Using Environment Object

The Environment object provides access to the environment variables and property values.

Example:

ExampleService.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

@Service
public class ExampleService {

private final Environment environment;

@Autowired
public ExampleService(Environment environment) {
this.environment = environment;
}

public void printAppInfo() {


String appName = environment.getProperty("app.name");
String appVersion = environment.getProperty("app.version");
System.out.println("App Name: " + appName);
System.out.println("App Version: " + appVersion);
}
}
Summary

●​ @Value is useful for injecting individual properties.


●​ @ConfigurationProperties is better for binding a set of related properties into a POJO.
●​ Environment can be used for more flexible access to properties, especially when
properties might be changed or retrieved dynamically.

Self Contained application


A self-contained application in the context of Spring Boot refers to an application that
packages all the necessary dependencies, configurations, and resources required to run
independently of external configurations. This approach is advantageous for deployment
and ensures that the application is portable and can run in any environment without
additional setup.

Spring Boot facilitates creating self-contained applications through several features:

1. Executable JAR/WAR

Spring Boot can package your application into a single executable JAR or WAR file,
which includes all dependencies and an embedded web server.

Example:

pom.xml

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

Run the following command to build the JAR file:

mvn clean package

This will create an executable JAR file in the target directory. You can run it using:

java -jar target/your-app-name.jar


2. Embedded Web Server

Spring Boot applications come with embedded web servers like Tomcat, Jetty, or
Undertow. This eliminates the need to deploy the application on an external server.

Example:

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class MyApplication {

public static void main(String[] args) {

SpringApplication.run(MyApplication.class, args);

3. Spring Boot DevTools

Spring Boot DevTools enhances the development experience by enabling features like
automatic restarts, live reload, and configurations specific to the development
environment.

Example:

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-devtools</artifactId>

<scope>runtime</scope>

</dependency>
4. Externalized Configuration

Spring Boot allows for externalized configuration, making it easy to manage different
configurations for various environments (development, testing, production).

application.properties

server.port=8080

spring.datasource.url=jdbc:mysql://localhost:3306/mydb

spring.datasource.username=user

spring.datasource.password=pass

You can override these properties using command-line arguments, environment variables,
or by providing different configuration files for each environment.

5. Spring Boot CLI

Spring Boot CLI is a command-line tool that can run Spring Boot applications directly
from Groovy scripts, which can be useful for quick prototyping and testing.

Example:

@RestController

class ThisWillActuallyRun {

@RequestMapping("/")

String home() {

return "Hello, World!"

}
Run it using:

spring run app.groovy

6. Spring Boot Initializr

Spring Boot Initializr is a web-based tool to quickly bootstrap a new Spring Boot project
with dependencies and configurations.

Access it at https://start.spring.io and generate a project with your desired dependencies.

Summary

Creating a self-contained Spring Boot application involves:

●​ Packaging as an executable JAR/WAR: Ensures the application is portable and


includes all dependencies.
●​ Using an embedded web server: Allows the application to run independently of
external servers.
●​ Externalized Configuration: Facilitates easy management of configurations across
different environments.
●​ Spring Boot DevTools: Enhances the development experience.
●​ Spring Boot CLI and Initializr: Provide tools to quickly prototype and initialize
projects.

Serialization and Deserialization


Serialization and deserialization are processes used to convert objects to and from a format that
can be easily stored or transmitted.

Serialization and Deserialization in Spring Boot

In a Spring Boot application, you often work with JSON or XML for serialization and
deserialization. Spring Boot provides support for these formats through Jackson and other
libraries.

Using Jackson for JSON Serialization and Deserialization


Jackson is a popular library for JSON processing in Java. Spring Boot includes Jackson by
default.

Example:

Person.java

import com.fasterxml.jackson.annotation.JsonProperty;

public class Person {


@JsonProperty("name")
private String name;

@JsonProperty("age")
private int age;

// constructor, getters, and setters


}

Serialization Example:
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

public class JsonSerializeDemo {


public static void main(String[] args) {
Person person = new Person("John Doe", 30);
ObjectMapper mapper = new ObjectMapper();

try {
String jsonString = mapper.writeValueAsString(person);
System.out.println("Serialized JSON: " + jsonString);
} catch (IOException e) {
e.printStackTrace();
}
}
}

Deserialization Example:
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;

public class JsonDeserializeDemo {


public static void main(String[] args) {
String jsonString = "{\"name\":\"John Doe\",\"age\":30}";
ObjectMapper mapper = new ObjectMapper();

try {
Person person = mapper.readValue(jsonString, Person.class);
System.out.println("Deserialized Person...");
System.out.println("Name: " + person.getName());
System.out.println("Age: " + person.getAge());
} catch (IOException e) {
e.printStackTrace();
}
}
}

Using Spring Boot's @RestController for JSON Serialization and Deserialization

In a Spring Boot application, you can also leverage the @RestController to automatically
serialize and deserialize JSON objects in HTTP requests and responses.

ExampleController.java

import org.springframework.web.bind.annotation.*;

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

@PostMapping("/person")
public Person createPerson(@RequestBody Person person) {
// Deserialize JSON to Person object
// Do something with the person object
return person; // Serialize Person object to JSON
}

@GetMapping("/person")
public Person getPerson() {
return new Person("Jane Doe", 25); // Serialize Person object to JSON
}
}

In this example, Spring Boot automatically handles the JSON serialization and deserialization
based on the @RequestBody and @ResponseBody annotations.

Summary

●​ Java Serialization: Use Serializable interface to convert objects to byte streams and vice
versa.
●​ Jackson for JSON: Use Jackson library for JSON serialization and deserialization.
●​ Spring Boot Integration: Leverage Spring Boot's built-in support for JSON handling in
RESTful APIs with @RestController.

Spring Boot provides integration with three JSON mapping libraries:


●​ Gson
●​ Jackson
●​ JSON-B
Jackson is the preferred and default library.

Jackson
Auto-configuration for Jackson is provided and Jackson is part of spring-boot-starter-json.
When Jackson is on the classpath an ObjectMapper bean is automatically configured.
Several configuration properties are provided for customizing the configuration of the
ObjectMapper.

Custom Serializers and Deserializers


If you use Jackson to serialize and deserialize JSON data, you might want to write your
own JsonSerializer and JsonDeserializer classes. Custom serializers are usually registered
with Jackson through a module, but Spring Boot provides an alternative
@JsonComponent annotation that makes it easier to directly register Spring Beans.
You can use the @JsonComponent annotation directly on JsonSerializer, JsonDeserializer
or KeyDeserializer implementations. You can also use it on classes that contain
serializers/deserializers as inner classes, as shown in the following example:
JSON properties
JSON Object
Objects are the mapping type in JSON. They map "keys" to "values". In JSON, the "keys" must
always be strings. Each of these pairs is conventionally referred to as a "property".

A JSON object contains zero, one, or more key-value pairs, also called properties. The object is
surrounded by curly braces {} . Every key-value pair is separated by a comma. The order of the
key-value pair is irrelevant.

In JSON (JavaScript Object Notation), properties (or keys) are used to define the structure and
data of JSON objects. Each property consists of a key-value pair, where the key is a string and
the value can be a string, number, boolean, array, object, or null.

The @JsonProperty annotation in Jackson is a versatile tool used to customize the serialization
and deserialization process of JSON in Java. It can be used to specify custom names for fields,
handle naming inconsistencies, and control how properties are serialized and deserialized.

Basic Structure of JSON

Here is a simple example of a JSON object with various property types:

"name": "John Doe",

"age": 30,

"isEmployee": true,

"address": {

"street": "123 Main St",

"city": "Anytown",

"zipcode": "12345"

},

"phoneNumbers": ["123-456-7890", "987-654-3210"],


"spouse": null

Common Uses of @JsonProperty

1.​ Custom Property Names

You can use @JsonProperty to specify a custom name for a field. This is useful when the JSON
property name does not match the Java field name.

Example:

import com.fasterxml.jackson.annotation.JsonProperty;

public class Person {


@JsonProperty("full_name")
private String name;

@JsonProperty("years_old")
private int age;

// getters and setters


}

Given the above class, a JSON representation would look like this:
{
"full_name": "John Doe",
"years_old": 30
}

2.​ Property Order

You can use @JsonProperty in conjunction with @JsonPropertyOrder to define the order in
which properties are serialized.

Example:

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonPropertyOrder({ "name", "age" })
public class Person {
@JsonProperty("name")
private String name;

@JsonProperty("age")
private int age;

// getters and setters


}

The JSON output will maintain the specified order:


{
"name": "John Doe",
"age": 30
}

3.​ Read-Only and Write-Only Properties

You can control whether a property is used only for serialization (write-only) or deserialization
(read-only).

Example:

import com.fasterxml.jackson.annotation.JsonProperty;

public class Person {


@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;

@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private int id;

private String name;

// getters and setters


}

This will ensure that password is included in JSON output but not expected in JSON input, and
id is expected in JSON input but not included in JSON output.
4.​ Default Values

You can specify default values for properties during deserialization.

Example:

import com.fasterxml.jackson.annotation.JsonProperty;

public class Person {


@JsonProperty(value = "name", defaultValue = "Unknown")
private String name;

@JsonProperty("age")
private int age;

// getters and setters


}

If the name property is missing in the JSON input, it will default to "Unknown".

5.​ Handling Collections and Maps

You can use @JsonProperty to handle collections and maps with custom keys and values.

Example:

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Map;

public class Person {


@JsonProperty("contacts")
private Map<String, String> contactDetails;

// getters and setters


}

A JSON representation could be:


{
"contacts": {
"home": "123-456-7890",
"work": "987-654-3210"
}
}

6.​ Using with Lombok

When using Lombok to generate boilerplate code, you can still use @JsonProperty to customize
JSON serialization and deserialization.

Example:

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Person {
@JsonProperty("full_name")
private String name;

@JsonProperty("years_old")
private int age;
}

Complete Example Code with Various Uses of @JsonProperty

Here’s a complete example demonstrating various uses of @JsonProperty:

Person.java

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import lombok.Getter;
import lombok.Setter;

import java.util.List;
import java.util.Map;

@Getter
@Setter
@JsonPropertyOrder({ "name", "age", "contacts", "id" })
public class Person {
@JsonProperty("full_name")
private String name;

@JsonProperty("years_old")
private int age;

@JsonProperty("contacts")
private Map<String, String> contactDetails;

@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private int id;

@JsonProperty(value = "hobbies", defaultValue = "[]")


private List<String> hobbies;

@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
}

Summary

●​ Custom Property Names: Map JSON keys to different field names in Java.
●​ Property Order: Specify the order of properties in the serialized JSON.
●​ Read-Only and Write-Only Properties: Control which properties are serialized or
deserialized.
●​ Default Values: Set default values for properties during deserialization.
●​ Collections and Maps: Handle complex data structures with custom keys and values.
●​ Integration with Lombok: Use @JsonProperty alongside Lombok annotations.

@JsonIgnore

This annotation helps us in ignoring certain properties of a Java class when it is getting serialized
to a JSON object.

Let’s first understand, why do you need such properties when you are going to ignore them
anyway. There could be various reasons like

1. You want to hide data from clients like password, Date of birth etc.
2. The client doesn’t want your unprocessed raw data like JSON String etc.

And to do this, what do you have to do? You have to just add a @JsonIgnore annotation above
the particular field or method.
public class User

private String name;


@JsonIgnore
private String password;

// We are still hiding it from the client in the Get Request

@JsonIgnore

public String getPassword()

return password;

// But allowing them to set it in the POST request

public void setPassword(String password)

this.password = password;

@JsonAlias
This annotation helps us in defining different alias for a JSON property to be mapped to a Java
field during deseralization.

Ex:

Imagine we are aggregating movies and tv series data from various streaming platform APIs and
storing it in our application class. Let’s assume, we have one Class for Movie and one for
TvSeries.

As we are getting data from various sources we can expect various naming convention of the
property name but we want to map similar data to one Java field right? And this is where
@JsonAlias comes into
the picture. How?

Let’s go through Movies class example.

public class Movie {

// This way our application will consider title, movieName and name all three
//during deserialization.

@JsonProperty("name")

@JsonAlias({"title", "movieName"})

private String name;

// Similarly here, it would consider all name like genre, type and category

@JsonProperty("genre")

@JsonAlias({"type", "category"})

private String genre;

For example, here we have two Java field where JSON property could have different name
depending on which API that data is coming from. So by giving alias such as title and
movieName we are telling our application that whenever it come across these property name in
JSON object it should set our name field. And by having @JsonProperty we can define a logical
property name for the Java field which will be used in both serialization and deserialization.
@Value Annotation

In Spring Boot, the @Value annotation is used to inject values into fields in your
Spring-managed beans. It is commonly used to inject values from property files (like
application.properties or application.yml) or environment variables.

Here’s how you can use the @Value annotation effectively:

1. Injecting Simple Values

You can inject simple values such as strings, numbers, or booleans directly into fields.

Example:

application.properties

app.name=MySpringApp
app.timeout=5000
app.debug=true

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class AppConfig {

@Value("${app.name}")
private String appName;

@Value("${app.timeout}")
private int timeout;

@Value("${app.debug}")
private boolean debug;

// Getters and Setters


}

In this example, appName will be injected with the value "MySpringApp", timeout
with 5000, and debug with true.
2. Injecting Values with Default Values

You can also specify default values using the @Value annotation.

Example:

@Value("${app.port:8080}") // Default value is 8080 if app.port is not set

private int port;

Ensure that the field you are injecting values into is private or has appropriate getters and
setters if you need to access it outside of the class.

The @Value annotation can be used with constructors and setter methods as well.

Schema
{ "type": "object" }
Data
{
"key": "value",
"another_key": "another_value"
}

{
"Sun": 1.9891e30,
"Jupiter": 1.8986e27,
"Saturn": 5.6846e26,
"Neptune": 10.243e25,
"Uranus": 8.6810e25,
"Earth": 5.9736e24,
"Venus": 4.8685e24,
"Mars": 6.4185e23,
"Mercury": 3.3022e23,
"Moon": 7.349e22,
"Pluto": 1.25e22
}
Using non-strings as keys is invalid JSON:
{
0.01: "cm",
1: "m",
1000: "km"
}

JSON properties
The properties (key-value pairs) on an object are defined using the properties keyword. The value of
properties is an object, where each key is the name of a property and each value is a schema used to
validate that property. Any property that doesn't match any of the property names in the properties
keyword is ignored by this keyword.
Schema
{
"type": "object",
"properties": {
"number": { "type": "number" },
"street_name": { "type": "string" },
"street_type": { "enum": ["Street", "Avenue", "Boulevard"] }
}
}
Data
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue" }

If we provide the number in the wrong type, it is invalid:


{ "number": "1600", "street_name": "Pennsylvania", "street_type": "Avenue" }

Required properties
By default, the properties defined by the properties keyword are not required. However, one can provide a
list of required properties using the required keyword.
The required keyword takes an array of zero or more strings. Each of these strings must be unique.
Schema
{
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string" },
"address": { "type": "string" },
"telephone": { "type": "string" }
},
"required": ["name", "email"]
}
Data
{
"name": "William Shakespeare",
"email": "[email protected]"
}

Providing extra properties is fine, even properties not defined in the schema:
{
"name": "William Shakespeare",
"email": "[email protected]",
"address": "Henley Street, Stratford-upon-Avon, Warwickshire, England",
"authorship": "in question"
}

Missing the required "email" property makes the JSON document invalid:
{
"name": "William Shakespeare",
"address": "Henley Street, Stratford-upon-Avon, Warwickshire, England",
}
In the above one email is missing.

Managing data access


Managing data access is a critical aspect of developing robust and secure applications. In
the context of Spring Boot, there are several approaches and tools available to manage
data access efficiently. These include using Spring Data JPA, Spring JDBC, and
implementing security measures to protect data access. Here’s an overview of these
approaches:

1. Spring Data JPA

Spring Data JPA simplifies the implementation of data access layers by providing a
repository abstraction over JPA (Java Persistence API). It allows you to perform CRUD
operations and complex queries with minimal boilerplate code.

Example Setup with Spring Data JPA

Dependencies in pom.xml:

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>

<groupId>com.h2database</groupId>

<artifactId>h2</artifactId>

<scope>runtime</scope>

</dependency>

Entity (Model) Class:

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

@Entity

public class User {

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

private Long id;

private String name;

private String email;

// getters and setters

}
Repository Interface:

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {

User findByEmail(String email);

By extending Spring Data's JpaRepository, we are granted an out-of-the-box set of


CRUD operations (save, findById, findAll, delete, deleteById, count, exists, and more).
We also have the ability to add custom finders purely by method signature (findByEmail
in this example). When Spring Data sees an interface extending its Repository marker
interface (which JpaRepository does), it creates a concrete implementation. It scans every
method, and parses their method signatures. Seeing findBy, it knows to look at the rest of
the method name, and start extracting property names based on the domain type (User).
Because it can see that User has an id,name,email etc,, it has enough information to
fashion a query. This also tips it off about expected criteria in the arguments (name).
Finally, Spring Data looks at the return type to decide what result set to assemble. The
entire query (not the query results), once assembled, is cached, so there is no overhead in
using the query multiple times.

Service Layer:

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import java.util.List;

@Service

public class UserService {

@Autowired

private UserRepository userRepository;

public User saveUser(User user) {

return userRepository.save(user);
}

public List<User> getAllUsers() {

return userRepository.findAll();

public User getUserByEmail(String email) {

return userRepository.findByEmail(email);

public void deleteUser(Long id) {

userRepository.deleteById(id);

Controller Layer:

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController

@RequestMapping("/api/users")

public class UserController {

@Autowired

private UserService userService;

@PostMapping
public User createUser(@RequestBody User user) {

return userService.saveUser(user);

@GetMapping

public List<User> getAllUsers() {

return userService.getAllUsers();

@GetMapping("/{email}")

public User getUserByEmail(@PathVariable String email) {

return userService.getUserByEmail(email);

@DeleteMapping("/{id}")

public void deleteUser(@PathVariable Long id) {

userService.deleteUser(id);

You might also like