Spring Boot MongoDB NoSQL API සිංහලෙන් | ඉක්මන් Coding Guide එකක්

ආයුබෝවන් කට්ටිය! කොහොමද ඉතින්? අද අපි කතා කරන්න යන්නේ දැන් ලෝකේ පුරාම trending වෙන, අපේ රටෙත් ගොඩක් අය use කරන, software development වලට මාරම පහසු වෙන technology දෙකක් ගැන: ඒ තමයි Spring Bootයි MongoDBයි. මේ දෙන්නව එකට join කරලා කොහොමද ඉක්මනට powerful REST API එකක් හදාගන්නේ කියලා තමයි මේ guide එකෙන් කියලා දෙන්නේ.
මොකද්ද මේ Spring Boot, මොකද්ද මේ MongoDB?
Spring Boot: ඉක්මන් API හදන මැජික් එක
Spring Boot කියන්නේ Java එකේ තියෙන Spring Framework එකේම එක කොටසක්. හැබැයි මේකේ විශේෂත්වය තමයි, ඔයාට පුළුවන් මේකෙන් බොහොම ඉක්මනට enterprise-grade applications, microservices, වගේම REST APIs පවා හදන්න. මේකේ තියෙන "convention over configuration" කියන concept එක නිසා boilerplate code ගොඩක් අඩු වෙනවා. ඒ කියන්නේ අනවශ්ය code ලියන්න ඕනේ නැහැ, system එකම ඔයාට අවශ්ය දේවල් automatically set කරනවා. ඔයාට focus කරන්න තියෙන්නේ application එකේ business logic එක විතරයි. ඒ වගේම මේකේ embedded servers (Tomcat, Jetty) එන නිසා war file deploy කරන්න, server setup කරන්න වගේ කරදර නැහැ. Directly run කරන්න පුළුවන්.
MongoDB: Flexible NoSQL Database එක
MongoDB කියන්නේ NoSQL database එකක්. ඒ කියන්නේ traditional relational databases (like MySQL, PostgreSQL) වගේ මේකේ tables, rows, schemas වගේ concept නෙමෙයි තියෙන්නේ. මේක document-oriented database එකක්. Data save වෙන්නේ JSON-like documents විදිහට. මේකේ ලොකුම වාසිය තමයි schema-less nature එක. ඒ කියන්නේ ඔයාට එක document එකක තියෙන field එකක් අනිත් document එකේ නැති වෙන්න පුළුවන්. ඒකෙන් data structure එක වෙනස් වෙද්දි database schema migrate කරන්න ඕන නැහැ. Scalability, high performance, flexibility මේකේ තියෙන තවත් වාසි. Big data applications, real-time analytics, mobile apps වගේ දේවල් වලට MongoDB මාරම හොඳයි.
ඇයි මේ දෙන්නා එකට?
Spring Boot එකේ simplicity එකයි, rapid development හැකියාවයි, MongoDB එකේ flexibility එකයි, scalability එකයි එකට join වුණාම, නියම combo එකක් හැදෙනවා. Spring Data MongoDB කියන project එකෙන් මේ දෙන්නව connect කරන එක මාරම ලේසි කරනවා. අපි බලමු කොහොමද මේක practically කරන්නේ කියලා.
අපි පටන් ගමු! Project Setup එක
මුලින්ම අපි Spring Boot project එකක් හදාගමු. මේකට හොඳම ක්රමය තමයි Spring Initializr use කරන එක. Browser එක open කරලා, ඒ site එකට යන්න.
Dependencies එකතු කරගනිමු
Spring Initializr එකේදී පහත dependencies ටික select කරගන්න:
- Spring Web: RESTful APIs හදන්න අවශ්ය tools සපයනවා.
- Spring Data MongoDB: Spring Boot application එක MongoDB එක්ක connect කරන්න, data operations කරන්න.
- Lombok (Optional): Boilerplate code (getters, setters, constructors) අඩු කරගන්න. Production වලදි නම් ටිකක් පරිස්සමින් use කරන්න ඕනේ.
Project Metadata section එකේ Group, Artifact, Name වගේ දේවල් ඔයාට ඕන විදිහට දාගන්න පුළුවන්. උදාහරණයක් විදිහට Group: `com.example`, Artifact: `mongodb-api`. Generate click කරලා project එක download කරගන්න. ඊට පස්සේ ඔයාගේ IDE (IntelliJ IDEA, VS Code, Eclipse වගේ) එකකින් project එක open කරගන්න.
application.properties/yml Configuration
Project එක open කරගත්තට පස්සේ `src/main/resources` folder එකේ තියෙන `application.properties` (නැත්නම් `application.yml`) file එක open කරලා, MongoDB connection details එකතු කරන්න. MongoDB locally run වෙනවා නම්, default port එක 27017.
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=my_mongodb_db_name # ඔයාට ඕන database එකේ නම
ඔයාට වෙන user, password එකක් තියෙනවා නම්, ඒවාත් add කරන්න පුළුවන්:
spring.data.mongodb.authentication-database=admin
spring.data.mongodb.username=myuser
spring.data.mongodb.password=mypassword
මේ configuration එකෙන් Spring Boot එකට කියනවා කොහෙද MongoDB database එක තියෙන්නේ කියලා.
Data Modeling සහ Repository එක
දැන් අපි data model එකක් හදමු. මේකට අපි `Product` කියලා model එකක් හදමු. මේකෙන් API එකෙන් expose කරන data structure එක define කරනවා.
Product Model එක
`com.example.mongodbapi.model` package එකක් හදලා ඒක ඇතුලේ `Product.java` කියලා class එකක් හදන්න.
package com.example.mongodbapi.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data // Lombok: Generates getters, setters, toString, equals, hashCode
@NoArgsConstructor // Lombok: Generates a no-argument constructor
@AllArgsConstructor // Lombok: Generates a constructor with all fields
@Document(collection = "products") // Specifies that this class maps to a MongoDB collection named "products"
public class Product {
@Id // Specifies this field as the document's primary key (_id in MongoDB)
private String id;
private String name;
private String description;
private double price;
private int quantity;
}
මේකේ තියෙන annotations ටික බලමු:
- `@Document(collection = "products")`: මේකෙන් කියවෙන්නේ `Product` class එක MongoDB එකේ `products` කියන collection එකට map වෙනවා කියලා. Collection එකක් කියන්නේ relational database එකක table එකක් වගේ.
- `@Id`: මේකෙන් කියවෙන්නේ `id` field එක තමයි MongoDB document එකේ primary key එක (`_id`) කියලා. MongoDB automatically string ID එකක් generate කරනවා.
- `@Data`, `@NoArgsConstructor`, `@AllArgsConstructor`: මේවා Lombok annotations. මේවා use කළාම getters, setters, constructors වගේ boilerplate code manualy ලියන්න ඕනේ නැහැ. Code එක clean වෙනවා.
Product Repository එක
දැන් අපි මේ `Product` model එක database එකත් එක්ක interact කරන්න අවශ්ය repository එක හදමු. `com.example.mongodbapi.repository` package එකක් හදලා ඒක ඇතුලේ `ProductRepository.java` කියලා interface එකක් හදන්න.
package com.example.mongodbapi.repository;
import com.example.mongodbapi.model.Product;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
@Repository // Marks this interface as a Spring repository
public interface ProductRepository extends MongoRepository<Product, String> {
// Spring Data MongoDB automatically provides basic CRUD operations:
// save(), findById(), findAll(), deleteById(), etc.
// You can also define custom query methods here, e.g.:
// List<Product> findByName(String name);
// List<Product> findByPriceGreaterThan(double price);
}
මෙහිදී, `ProductRepository` එක `MongoRepository` extend කරනවා. `MongoRepository<Product, String>` කියන්නේ මොකද්ද? `Product` කියන්නේ අපි හදාගත්ත model class එක. `String` කියන්නේ ඒ model එකේ ID field එකේ data type එක (`id` field එක String නිසා). `MongoRepository` එක extend කළාම, Spring Data MongoDB automatically අපිට save, findById, findAll, delete වගේ standard CRUD (Create, Read, Update, Delete) operations වලට අවශ්ය methods ටික generate කරලා දෙනවා. ඔයාට ඒ methods ලියන්න ඕනේ නැහැ! මේක මාරම පහසුයි නේද?
ඒ වගේම, ඔයාට අවශ්ය නම් custom query methods define කරන්නත් පුළුවන්. උදාහරණයක් විදිහට, `findByName(String name)` කියලා method එකක් දැම්මොත්, Spring Data MongoDB ඒකෙන් database එකේ `name` එක අනුව search කරන query එක automatically හදනවා. ෂෝක් නේද?
API එක හදමු! Controller Layer එක
අන්තිමට, අපි REST API endpoints හදමු. මේකට `com.example.mongodbapi.controller` package එකක් හදලා ඒක ඇතුලේ `ProductController.java` කියලා class එකක් හදන්න.
package com.example.mongodbapi.controller;
import com.example.mongodbapi.model.Product;
import com.example.mongodbapi.repository.ProductRepository;
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 // Marks this class as a REST Controller
@RequestMapping("/api/products") // Base URL for all endpoints in this controller
public class ProductController {
@Autowired // Injects the ProductRepository instance
private ProductRepository productRepository;
// Create a new Product
@PostMapping
public ResponseEntity<Product> createProduct(@RequestBody Product product) {
try {
Product savedProduct = productRepository.save(product);
return new ResponseEntity<>(savedProduct, HttpStatus.CREATED);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
// Get all Products
@GetMapping
public ResponseEntity<List<Product>> getAllProducts() {
try {
List<Product> products = productRepository.findAll();
if (products.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}s
return new ResponseEntity<>(products, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
// Get Product by ID
@GetMapping("/{id}")
public ResponseEntity<Product> getProductById(@PathVariable("id") String id) {
Optional<Product> productData = productRepository.findById(id);
return productData.map(product -> new ResponseEntity<>(product, HttpStatus.OK))
.orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
// Update a Product
@PutMapping("/{id}")
public ResponseEntity<Product> updateProduct(@PathVariable("id") String id, @RequestBody Product product) {
Optional<Product> productData = productRepository.findById(id);
if (productData.isPresent()) {
Product _product = productData.get();
_product.setName(product.getName());
_product.setDescription(product.getDescription());
_product.setPrice(product.getPrice());
_product.setQuantity(product.getQuantity());
return new ResponseEntity<>(productRepository.save(_product), HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
// Delete a Product
@DeleteMapping("/{id}")
public ResponseEntity<HttpStatus> deleteProduct(@PathVariable("id") String id) {
try {
productRepository.deleteById(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
// You can add a custom search endpoint if you defined findByName in repository
@GetMapping("/search")
public ResponseEntity<List<Product>> getProductsByName(@RequestParam String name) {
// Assuming findByName(String name) method is defined in ProductRepository
// List products = productRepository.findByName(name);
// return new ResponseEntity<>(products, HttpStatus.OK);
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); // Placeholder
}
}
මේ controller එකේ තියෙන වැදගත් දේවල් ටික බලමු:
- `@RestController`: මේකෙන් කියවෙන්නේ මේ class එක REST API requests handle කරන controller එකක් කියලා.
- `@RequestMapping("/api/products")`: මේක base URL එක. මේ controller එකේ හැම endpoint එකකටම කලින් `/api/products` prefix එක add වෙනවා.
- `@Autowired private ProductRepository productRepository;`: මේකෙන් කියවෙන්නේ Spring Framework එකට `ProductRepository` එකේ instance එකක් automatically inject කරන්න කියලා. ඒ කියන්නේ අපිට ඒක use කරන්න පුළුවන්.
- `@PostMapping`, `@GetMapping`, `@PutMapping`, `@DeleteMapping`: මේවා HTTP methods වලට map වෙන annotations.
- `@PostMapping`: New resource එකක් create කරන්න (e.g., POST request to `/api/products` to create a new product). `@RequestBody` එකෙන් request body එකේ එන JSON object එක `Product` object එකකට convert කරනවා.
- `@GetMapping`: Resources retrieve කරන්න. Path variable (`/{id}`) එකක් එක්ක ID එකෙන් retrieve කරන්න පුළුවන්, නැත්නම් parameter නැතුව හැම product එකක්ම retrieve කරන්න පුළුවන්.
- `@PutMapping`: Existing resource එකක් update කරන්න.
- `@DeleteMapping`: Resource එකක් delete කරන්න.
- `ResponseEntity`: මේකෙන් අපිට පුළුවන් HTTP status codes (200 OK, 201 CREATED, 404 NOT_FOUND, 500 INTERNAL_SERVER_ERROR) එක්කම response එකක් යවන්න. Error handling වලට මේක වැදගත්.
දැන් ඔයාට පුළුවන් Postman, Insomnia, නැත්නම් curl වගේ tool එකක් use කරලා මේ API එක test කරන්න.
Example requests:
1. Product එකක් Create කරන්න (POST)
POST http://localhost:8080/api/products
Content-Type: application/json
{
"name": "Laptop",
"description": "Powerful gaming laptop",
"price": 1200.00,
"quantity": 10
}
2. හැම Products ටිකම ගන්න (GET)
GET http://localhost:8080/api/products
3. ID එකෙන් Product එකක් ගන්න (GET)
GET http://localhost:8080/api/products/<generated_product_id>
4. Product එකක් Update කරන්න (PUT)
PUT http://localhost:8080/api/products/<existing_product_id>
Content-Type: application/json
{
"name": "Gaming Laptop",
"description": "Updated description for gaming laptop",
"price": 1150.00,
"quantity": 8
}
5. Product එකක් Delete කරන්න (DELETE)
DELETE http://localhost:8080/api/products/<existing_product_id>
පොඩි Tips ටිකක්
- Error Handling: Production applications වලදී error handling හොඳට කරන්න ඕනේ. `try-catch` blocks වලට අමතරව Spring Boot එකේ Global Exception Handling (using `@ControllerAdvice`) use කරන්න පුළුවන්.
- Validation: Client එකෙන් එන data validate කරන්න Spring Boot Validation API (JSR 380) use කරන්න පුළුවන්. `@Valid` annotation එක use කරලා, POJO එකේ `@NotNull`, `@Min`, `@Max` වගේ annotations දාන්න පුළුවන්.
- Security: Production APIs වලට Spring Security use කරලා Authentication සහ Authorization add කරන්න අමතක කරන්න එපා.
- Pagination & Sorting: ලොකු data sets එක්ක වැඩ කරද්දී, `MongoRepository` එකෙන් provide කරන `Pageable` සහ `Sort` interfaces use කරලා pagination සහ sorting easily implement කරන්න පුළුවන්.
- Custom Queries: `MongoRepository` එකේදී `findBy` prefix එක use කරලා complex queries define කරන්න පුළුවන්. නැත්නම් `@Query` annotation එක use කරලා MongoDB JSON query syntax එක direct ලියන්නත් පුළුවන්.
ඉතින් කොහොමද?
දැන් ඔයාට Spring Boot සහ MongoDB use කරලා basic REST API එකක් හදාගන්න පුළුවන්. මේක පටන් ගන්න හොඳම තැන. ඔයාට පුළුවන් මේක customize කරලා, තවත් features add කරලා, ඔයාගේම project එකකට මේ knowledge එක apply කරන්න. NoSQL databases වල flexibility එකයි, Spring Boot එකේ development speed එකයි එක්ක වැඩ කරන එක මාරම ආතල් වැඩක් කියලා ඔයාටත් තේරෙයි අනිවාරෙන්!
මේ article එක ගැන ඔයාගේ අදහස්, ප්රශ්න පහලින් comment එකක් දාගෙනම යන්න. අලුත් මොනවහරි ඉගෙන ගත්තා නම් යාළුවන්ටත් share කරන්න අමතක කරන්න එපා. ජය වේවා!