Build RESTful CRUD APIs using Spring Boot and PostgreSQL

 To build RESTful CRUD APIs using Spring Boot and PostgreSQL, follow the steps below to create the project structure and implement basic operations (Create, Read, Update, Delete) for a resource, such as Product.

Prerequisites:

  • Java Development Kit (JDK)
  • Maven or Gradle
  • Spring Boot
  • PostgreSQL database running locally or remotely
  • IDE (e.g., IntelliJ IDEA, Eclipse)

Steps:

1. Create a Spring Boot Project

You can create a Spring Boot project using Spring Initializr (https://start.spring.io/), or through your IDE. Include the following dependencies:

  • Spring Web: For building REST APIs.
  • Spring Data JPA: For interacting with the database.
  • PostgreSQL Driver: For connecting to PostgreSQL.
  • Spring Boot DevTools (optional for live reloads during development).

2. Project Structure

Here’s the typical project structure for your RESTful CRUD API:

spring-boot-crud │ ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ └── example │ │ │ └── crud │ │ │ ├── controller │ │ │ │ └── ProductController.java │ │ │ ├── model │ │ │ │ └── Product.java │ │ │ ├── repository │ │ │ │ └── ProductRepository.java │ │ │ ├── service │ │ │ │ └── ProductService.java │ │ │ └── CrudApplication.java │ ├── resources │ │ ├── application.properties │ │ └── static │ │ └── index.html └── pom.xml (or build.gradle)

3. Setup application.properties

In src/main/resources/application.properties, configure your PostgreSQL connection:

spring.datasource.url=jdbc:postgresql://localhost:5432/your_db_name spring.datasource.username=your_username spring.datasource.password=your_password spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.format_sql=true spring.jpa.show-sql=true spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect server.port=8080

Make sure PostgreSQL is running and replace the values of your_db_name, your_username, and your_password with your PostgreSQL database details.

4. Create the Product Entity

Create a model class that maps to the product table in PostgreSQL.

package com.example.crud.model; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; @Entity public class Product { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private double price; // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } }

5. Create the ProductRepository

The repository interface extends JpaRepository to handle CRUD operations automatically.

package com.example.crud.repository; import com.example.crud.model.Product; import org.springframework.data.jpa.repository.JpaRepository; public interface ProductRepository extends JpaRepository<Product, Long> { }

6. Create the ProductService

The service class contains the business logic for interacting with the repository.

package com.example.crud.service; import com.example.crud.model.Product; import com.example.crud.repository.ProductRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; @Service public class ProductService { @Autowired private ProductRepository productRepository; // Create or Update Product public Product saveProduct(Product product) { return productRepository.save(product); } // Get All Products public List<Product> getAllProducts() { return productRepository.findAll(); } // Get Product by ID public Optional<Product> getProductById(Long id) { return productRepository.findById(id); } // Delete Product public void deleteProduct(Long id) { productRepository.deleteById(id); } }

7. Create the ProductController

The controller handles HTTP requests and communicates with the service layer.

package com.example.crud.controller; import com.example.crud.model.Product; import com.example.crud.service.ProductService; 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; import java.util.Optional; @RestController @RequestMapping("/api/products") public class ProductController { @Autowired private ProductService productService;

// Update Product @PutMapping("/{id}") public ResponseEntity<Product> updateProduct(@PathVariable Long id, @RequestBody Product product) { if (!productService.getProductById(id).isPresent()) { return ResponseEntity.notFound().build(); } product.setId(id); // Ensure the ID in the path matches the ID in the request Product updatedProduct = productService.saveProduct(product); return ResponseEntity.ok(updatedProduct); } // Create or Update Product @PostMapping public ResponseEntity<Product> createOrUpdateProduct(@RequestBody Product product) { Product savedProduct = productService.saveProduct(product); return new ResponseEntity<>(savedProduct, HttpStatus.CREATED); } // Get All Products @GetMapping public List<Product> getAllProducts() { return productService.getAllProducts(); } // Get Product by ID @GetMapping("/{id}") public ResponseEntity<Product> getProductById(@PathVariable Long id) { Optional<Product> product = productService.getProductById(id); return product.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build()); } // Delete Product @DeleteMapping("/{id}") public ResponseEntity<Void> deleteProduct(@PathVariable Long id) { productService.deleteProduct(id); return ResponseEntity.noContent().build(); } }

8. Main Application Class

The main Spring Boot application class to run the application.

package com.example.crud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class CrudApplication { public static void main(String[] args) { SpringApplication.run(CrudApplication.class, args); } }

9. Running the Application

  • Ensure that your PostgreSQL database is running and the credentials are correct.
  • Run the application with the command:
bash
mvn spring-boot:run

or from your IDE.

10. Testing the API

You can use Postman or any HTTP client to test the CRUD operations:

  • Create Product (POST):

    • URL: http://localhost:8080/api/products
    • Body (JSON):
      json
      { "name": "Product A", "price": 20.5 }
  • Get All Products (GET):

    • URL: http://localhost:8080/api/products
  • Get Product by ID (GET):

    • URL: http://localhost:8080/api/products/{id}
  • Update Product (PUT):

    • URL: http://localhost:8080/api/products
    • Body (JSON):
      json

      { "id": 1, "name": "Updated Product", "price": 30.0 }
  • Delete Product (DELETE):

    • URL: http://localhost:8080/api/products/{id}

Conclusion

This is a basic setup for building a RESTful CRUD API using Spring Boot and PostgreSQL. You can further enhance it by adding validation, error handling, logging, pagination, and more features depending on the requirements of your application.

Comments