[৮.৫] CRUD ফাংশনালিটির প্রয়োগ (Applying CRUD functionality)
এতক্ষণ ধরে যা করেছি আমরা তা ছিল প্রজেক্ট স্ট্রাকচারিং। একটা প্রজেক্টের কোথায় কি হচ্ছে, কি ধরণের সমস্যায় কোথায় চেক করা প্রয়োজন, আর কোথাও পরিবর্তন আনা লাগলে সেটা যাতে সহজে করা যায়, ইত্যাদি নানাবিধ কাজের সুবিধার জন্য আমাদের এই স্ট্রাকচারিং এর প্রয়োজন ছিল।
এখন আমরা কাজ করা শুরু করব আমাদের CRUD API এর উপর। একাধারে প্রত্যেক রিকোয়েস্ট কিভাবে হ্যান্ডেল করব, রেসপন্স কিভাবে তৈরি করব এবং ডাটাবেসের সাথে কিভাবে যোগাযোগ রক্ষা করব তার সবই পর্যায়ক্রমে ইমপ্লিমেন্ট করব এখন আমরা।
- রেসপন্স সম্পর্কে কিছু কথা –
controllers/book.go থেকে আমরা সবধরনের রেসপন্স ইউজারের কাছে রিটার্ন করব। সুতরাং আমাদের এই রেসপন্সের গঠনটা কেমন হবে তা আমাদের জন্য জানা জরুরি। একটি রেসপন্সের উদাহরণ দিয়ে বাকি ব্যাখ্যা দেয়া হলো –
e.JSON(http.StatusCreated, "Book was created successfully")
এখানে e.JSON() এ ২ টা ভ্যালু পাস করা যায়। এক হচ্ছে স্ট্যাটাস কোড এবং অপরটি হলো যেকোনো কিছু । উপরে আমরা http.StatusCreated দ্বারা বুঝিয়েছি স্ট্যাটাস কোড 201 কে, যেটা দ্বারা একজন ডেভেলপার বুঝতে পারবে যে এখানে কিছু একটার Create/Update সাকসেসফুল হয়েছে। দ্বিতীয় ভ্যালুর জন্য আমরা যেকোনো কিছু পাস করতে পারি যা রিকোয়েস্ট কারীর কাছে তথ্যবহুল এবং সহজবোধ্য হলে ভালো হয়।
রেসপন্সের বিষয়ে এই বেসিকটা জানানোর উদ্দেশ্য হলো, কন্ট্রোলারে আমাদের এই রেসপন্স নিয়ে বার বার কাজ করতে হবে। সেখানে আরো অনেক স্ট্যাটাস কোড ব্যবহার দেখতে পাবো। বিভিন্ন স্ট্যাটাস কোড সম্পর্কে জানার জন্য এই লিংকটি সাহায্য করবে।
শুরু করা যাক তাহলে এই অংশের কাজ…
[৮.৫.১] Create এর আদি-অন্ত
শুরুতেই আমরা কাজ শুরু করব CRUD এর প্রথম ফাংশনালিটি, Create নিয়ে :
- controllers/book.go এ –
- আমাদের প্রথম কাজ হবে controllers/book.go এর CreateBook() ফাংশনে। নতুন বই Create করার জন্য প্রয়োজনীয় যে ইনপুট গুলো আছে সেগুলো আমাদের বানিয়ে নেয়া কাস্টম Struct, BookRequest এর একটি ইন্সট্যান্স reqBook সাথে Bind করে দেবো –
reqBook := &types.BookRequest{}
if err := e.Bind(reqBook); err != nil {
return e.JSON(http.StatusBadRequest, "Invalid Data")
}
2. ECHO তে আগত কোনো রিকোয়েস্টের ডাটা Bind দ্বারা কোনো Struct বা Map এ নেয়া যায়। উপরের Bind ফাংশন দ্বারাও Book Create করার যাবতীয় ডাটা আমরা রিকোয়েস্ট বডি থেকে reqBook এ ম্যাপ করে দিয়েছি।
3. পরবর্তী ধাপে reqBook এর ফিল্ড ডাটা গুলো models.Book এর একটি ইন্সট্যান্সে নেবো। কারণ ডাটাবেস টেবিলে নতুন Book রাখতে গেলে টেবিলের স্কিমা Struct এর প্রয়োজন পড়ে –
book := &models.Book{
BookName: reqBook.BookName,
Author: reqBook.Author,
Publication: reqBook.Publication,
}
4. এবারে আমরা এই book Struct টি সার্ভিসে পাঠিয়ে দেবো যাতে করে সার্ভিস ডাটাবেস ফাংশনকে এটা পাঠাতে পারে –
if err := BookService.CreateBook(book); err != nil {
return e.JSON(http.StatusInternalServerError, err.Error())
}
return e.JSON(http.StatusCreated, "Book was created successfully")
5. উপরে BookService এর CreateBook() মেথডটি ব্যবহৃত হয়েছে, যা ডাটাবেস টেবিলে নতুন Book Create করা গেলে বা না গেলে রেসপন্স রিটার্ন করবে এবং সে অনুযায়ী কন্ট্রোলার থেকে রেসপন্স রিটার্ন করা হবে। এর জন্য আমাদের “Go-bootcamp/pkg/services” প্যাকেজটি ইমপোর্ট করা লাগবে।
6. তাহলে controllers/book.go এর CreateBook() ফাংশনের ফাইনাল রূপ হচ্ছে :
controllers/book.go
func CreateBook(e echo.Context) error {
reqBook := &types.BookRequest{}
if err := e.Bind(reqBook); err != nil {
return e.JSON(http.StatusBadRequest, "Invalid Data")
}
if err := reqBook.Validate(); err != nil {
return e.JSON(http.StatusBadRequest, err.Error())
}
book := &models.Book{
BookName: reqBook.BookName,
Author: reqBook.Author,
Publication: reqBook.Publication,
}
if err := BookService.CreateBook(book); err != nil {
return e.JSON(http.StatusInternalServerError, err.Error())
}
return e.JSON(http.StatusCreated, "Book was created successfully")
}
- services/book.go এ –
7. controllers/book.go এর CreateBook() থেকে services/book.go এর CreateBook() এ models.Book এর একটি ইন্সট্যান্স পাঠানো হয়েছে। সেটা এখন repositories/book.go এর CreateBook() মেথডে পাস করব । যেটা IBookRepo এর repo তে রাখা ইন্সট্যান্স দ্বারা সম্ভব হবে। এর জন্য আমাদের “Go-bootcamp/pkg/repositories” প্যাকেজটি ইমপোর্ট করা লাগবে
– services/book.go
func (service *BookService) CreateBook(book *models.Book) error {
if err := service.repo.CreateBook(book); err != nil {
return errors.New("book was not created")
}
return nil
}
8. এখানে ডাটাবেসের CreateBook() মেথড ব্যবহার করে যদি নতুন Book টেবিলে না Create করা যায়, সেক্ষেত্রে এরর রিটার্ন হবে এবং সার্ভিসে “book was not created” রেসপন্স টি তৈরি হয়ে তা কন্ট্রোলারে রিটার্ন করবে।
9. repositories/book.go এ –
10. সবশেষে ডাটাবেসের সাথে সরাসরি যোগাযোগের জন্য repositories/book.go এর CreateBook() মেথড models.Book এর একটি ইন্সট্যান্স রিসিভ করেছে। সেটা GORM এর Create মেথড ব্যবহার করে, টেবিলে যোগ করে দেবো এবং সম্ভব না হলে এরর রিটার্ন করা হবে –
repositories/book.go
func (repo *bookRepo) CreateBook(book *models.Book) error {
if err := repo.db.Create(book).Error; err != nil {
return err
}
return nil
}
11. এখানে repo.db হচ্ছে আমাদের লোকালি স্টোর করা *gorm.DB এর ইন্সট্যান্স।
POSTMAN এর ব্যবহার
ভালো হয় যদি একটা ফাংশনালিটি নিয়ে কাজ করা শেষে সেটা সাথে সাথে চেক করা হয়। “localhost:9030/bookstore/book” route এ নিচের json ভ্যালু টা চালিয়ে আমরা Create ফাংশনালিটি ঠিকঠাক শেষ করতে পেরেছি কিনা তা চেক করতে পারি –
{
"bookname" : "Killing Floor",
"author" : "Lee Child",
"publication" : "Oxford Press"
}
- যদি আমাদের কোড ঠিকঠাক থাকে তাহলে Postman এ রেসপন্স আসবে “Book was created successfully“ রেফারেন্স হিসেবে নিচের ছবি টা দেখতে পারি –
[৮.৫.২] Read এর আদি-অন্ত
এবারে কাজ শুরু করব CRUD এর দ্বিতীয় ফাংশনালিটি, Read নিয়ে :
- controllers/book.go এ –
- আমাদের প্রথম কাজ হবে controllers/book.go এর GetBooks() ফাংশনে। আমরা আমাদের GetBooks() ফাংশনে ২ ধরণের কাজ করব –
- বই এর নির্দিষ্ট ID পাঠালে শুধু ওই বই এর ডিটেইলস রেসপন্সে পাবো।
- আর কোনো নির্দিষ্ট ID না পাঠানো হলে সব বইয়ের একটা সামারি লিস্ট রেসপন্স হিসেবে পাঠাবো।
- এর জন্য আমরা শুরুতেই echo.Context অবজেক্ট থেকে কুয়েরি প্যারামিটার হিসেবে bookID এর কোনো মান আছে কিনা সেটা চেক করব ।
tempBookID := e.QueryParam("bookID")
3. এরপর প্রাপ্তভ্যালুটি পার্স করে ইন্টিজারে রূপান্তর করে দেখবো আদৌ কোনো ভ্যালু দেয়া হয়েছে কিনা।
4. এরপর BookService এর মেথড GetBooks() এ এই bookID পাস করব এবং রেসপন্সের অপেক্ষা করব।
controllers/book.go
func GetBooks(e echo.Context) error {
tempBookID := e.QueryParam("bookID")
bookID, err := strconv.ParseInt(tempBookID, 0, 0)
if err != nil && tempBookID != "" {
return e.JSON(http.StatusBadRequest, "Enter a valid book ID")
}
book, err := BookService.GetBooks(uint(bookID))
if err != nil {
return e.JSON(http.StatusBadRequest, err.Error())
}
return e.JSON(http.StatusOK, book)
}
5. যদি সার্ভিস থেকে এরর রিটার্ন হয়, সেক্ষেত্রে সেটা ফাইনাল রেসপন্স হিসেবে রিটার্ন করা হবে। অন্যথা নির্দিষ্ট বই বা বই এর সমষ্টি ফাইনাল রেসপন্স হিসেবে রিটার্ন করা হবে।
- services/book.go এ –
6. services/book.go এর GetBooks() মেথড bookID রিসিভ করে এবং তা ব্যবহার করে repositories/book.go এর GetBooks() মেথডকে কল করেছে।
7. এরপর রেসপন্স হিসেবে models.Book এর একটি অ্যারে আসবে। যদি অ্যারে টি শূন্য হয়ে থাকে তাহলে “no book found” রেসপন্স টি কন্ট্রোলারে রিটার্ন করবে।
8. যদি অ্যারে শূন্য না হয়ে থাকে তাহলে তা types.BookRequest এর অ্যারে, যা আমাদের তৈরি একটি কাস্টম Struct, তাতে পরিবর্তন করে রিটার্ন করব।
9. এমনটা করার কারণ হলো, আমরা models.Book Struct টি শুধু ডাটাবেসের অপারেশনের কাজে ব্যবহার করব।
services/book.go
func (service *BookService) GetBooks(bookID uint) ([]types.BookRequest, error) {
var allBooks []types.BookRequest
book := service.repo.GetBooks(bookID)
if len(book) == 0 {
return nil, errors.New("no book found")
}
for _, val := range book {
allBooks = append(allBooks, types.BookRequest{
ID: val.ID,
BookName: val.BookName,
Author: val.Author,
Publication: val.Publication,
})
}
return allBooks, nil
}
- repositories/book.go এ –
10. repositories/book.go এ GetBooks() মেথডে bookID রিসিভ করার পর bookID এর এভেইলেবিলিটি অনুযায়ী GORM এর Find মেথড ব্যবহার করে প্রাপ্ত ডাটার সারিগুলো models.Book এর একটি অ্যারেতে রেখে রিটার্ন করবে।
repositories/book.go
func (repo *bookRepo) GetBooks(bookID uint) []models.Book {
var Book []models.Book
var err error
if bookID != 0 {
err = repo.db.Where("id = ?", bookID).Find(&Book).Error
} else {
err = repo.db.Find(&Book).Error
}
if err != nil {
return []models.Book{}
}
return Book
}
-
POSTMAN এর ব্যবহার
- bookID কুয়েরি প্যারামিটার ছাড়া রেসপন্স –
[
{
"bookID": 1,
"bookname": "Last Kill",
"author": "Lee Child",
"publication": "Oxford Press"
},
{
"bookID": 2,
"bookname": "Killing Floor",
"author": "Lee Child",
"publication": "Oxford Press"
}
]
Postman রেফারেন্স –
- bookID কুয়েরি প্যারামিটার সহ রেসপন্স- (localhost:9030/bookstore/book?bookID=2)
[
{
"bookID": 2,
"bookname": "Killing Floor",
"author": "Lee Child",
"publication": "Oxford Press"
}
]
Postman রেফারেন্স –
[৮.৫.৩] Update এর আদি-অন্ত
এবারে কাজ শুরু করব CRUD এর তৃতীয় ফাংশনালিটি, Update নিয়ে :
- controllers/book.go এ –
- কাজ গুলোই অনেকটা পুনরাবৃত্তি হচ্ছে। আসলেও তাই। বলা যায় এই অংশ Create, Read এর সমন্বয়ে গঠিত অনেকটাই।
2. প্রথমেই Update করার জন্য প্রয়োজনীয় যে ইনপুট গুলো আছে সেগুলো আমাদের বানিয়ে নেয়া কাস্টম Struct, BookRequest এর একটি ইন্সট্যান্স reqBook সাথে Bind করে দেবো –
reqBook := &types.BookRequest{}
if err := e.Bind(reqBook); err != nil {
return e.JSON(http.StatusBadRequest, "Invalid Data")
}
3. echo.Context অবজেক্ট থেকে প্যারামিটার হিসেবে bookID এর মান বের করব এবং তা পার্স করে ইন্টিজারে রূপান্তর করব। কেননা প্যারামিটার ছাড়া আমরা নির্দিষ্ট বই এর ভ্যালু Update করতে পারব না –
tempBookID := e.Param("bookID")
bookID, err := strconv.ParseUint(tempBookID, 0, 0)
if err != nil {
return e.JSON(http.StatusBadRequest, "Enter a valid book ID")
}
4. এবার আমরা পূর্বের Read ফাংশনালিটি ব্যবহার করব অর্থাৎ আবার সার্ভিসের GetBooks() মেথডকে কল করব এটা দেখতে যে উক্ত bookID সম্বলিত কোনো বই আমাদের ডাটাবেসে আছে কিনা। আগের মতই এক্ষেত্রেও একটি অ্যারে রিটার্ন করবে এবং অ্যারের সাইজ যদি ০ না হয়ে থাকে তাহলে বুঝব যে বইটি ডাটাবেসে বিদ্যমান আছে আর ০ হয়ে থাকলে আমরা সার্ভিস থেকেই একটি এরর রেসপন্স পাবো –
existingBook, err := BookService.GetBooks(uint(bookID))
if err != nil {
return e.JSON(http.StatusBadRequest, err.Error())
}
5. এরপর models.Book এর নতুন একটি ইন্সট্যান্সে পরিবর্তিত ভ্যালু গুলো সেট করব –
updatedBook := &models.Book{
ID: uint(bookID),
BookName: existingBook[0].BookName,
Author: existingBook[0].Author,
Publication: existingBook[0].Publication,
}
6. এবারে পরিবর্তিত ভ্যালুগুলো সহ models.Book এর ইন্সট্যান্সটি আমরা services/book.go এর UpdateBook() মেথডে পাঠাবো এবং এবং সার্ভিস থেকে আসা রেসপন্স অনুযায়ী ফাইনাল রেসপন্স গঠন করব।
7. তাহলে কন্ট্রোলারে ফাইনাল কোড দাঁড়াচ্ছে –
controllers/book.go
func UpdateBook(e echo.Context) error {
reqBook := &types.BookRequest{}
if err := e.Bind(reqBook); err != nil {
return e.JSON(http.StatusBadRequest, consts.InvalidInput)
}
if err := reqBook.Validate(); err != nil {
return e.JSON(http.StatusBadRequest, err.Error())
}
tempBookID := e.Param("bookID")
bookID, err := strconv.ParseUint(tempBookID, 0, 0)
if err != nil {
return e.JSON(http.StatusBadRequest, consts.InvalidID)
}
existingBook, err := BookService.GetBooks(uint(bookID))
if err != nil {
return e.JSON(http.StatusBadRequest, err.Error())
}
updatedBook := &models.Book{
ID: uint(bookID),
BookName: existingBook[0].BookName,
Author: existingBook[0].Author,
Publication: existingBook[0].Publication,
}
if err := BookService.UpdateBook(updatedBook); err != nil {
return e.JSON(http.StatusInternalServerError, err.Error())
}
return e.JSON(http.StatusCreated, "Book was updated successfully")
}
- services/book.go এ –
8. services/book.go এর UpdateBook() মেথড থেকে repositories/book.go এর UpdateBook() মেথডে নতুন প্রাপ্ত models.Book এর ইন্সট্যান্সটি পাঠিয়ে দেবো এবং এররের অপেক্ষা করব।
9. এরর রিটার্ন হলে “book update was unsuccesful” রেসপন্স তৈরি কর কন্ট্রোলারে রিটার্ন করা হবে – services/book.go
services/book.go
func (service *BookService) UpdateBook(book *models.Book) error {
if err := service.repo.UpdateBook(book); err != nil {
return errors.New("book update was unsuccesful")
}
return nil
}
- repositories/book.go এ –
10. repositories/book.go এ models.Book এর ইন্সট্যান্সটি রিসিভ করার পর, উক্ত models.Book এর ID অনুসারে GORM এর Save মেথড ব্যবহার করে উক্ত সারির সকল পরিবর্তিত ভ্যালু Update হয়ে যাবে –
repositories/book.go
func (repo *bookRepo) UpdateBook(book *models.Book) error {
if err := repo.db.Save(book).Error; err != nil {
return err
}
return nil
}
11. অন্যথা, Update না হয়ে থাকলে সার্ভিসে এরর রিটার্ন করবে এবং সে অনুযায়ী রেসপন্স জেনারেট হবে।
POSTMAN এর ব্যবহার
“localhost:9030/bookstore/book/1” route এ নিচের json ভ্যালু, PUT রিকোয়েস্ট হিসেবে পাঠিয়ে, আমরা Update ফাংশনালিটি ঠিকঠাক শেষ করতে পেরেছি কিনা তা চেক করতে পারি –
- আমাদের ডাটাবেসের টেবিল তৈরির সবকিছু connection/connection.go তে থাকলেও আমরা কিন্তু কোথাও থেকে তা কল করিনি অর্থাৎ ডাটাবেসের কোন ইন্সট্যান্স তৈরি করিনি। কারণ, যখন আমরা connection/connection.go এর কাজ শেষ করেছিলাম তখনো ডাটাবেস ব্যবহার করা হচ্ছিল না কোথাও। আমরা জানি, ব্যবহার না করে কোনো ইন্সট্যান্স ফেলে রাখা যায়না Go তে।
আগেই বলেছিলাম আমরা ফিরে আসব containers/serve.go তে :
- যখন আমরা *gorm.DB এর ইন্সট্যান্সের সাথে repositories/book.go এ IBookRepo ইন্টারফেস বাইন্ড করেছিলাম BookDBInstance() ফাংশনের দ্বারা, তখন সেখানে *gorm.DB এর একটি ইন্সট্যান্স রিসিভ করেছিলাম। কিন্তু সেটা কোথা থেকে আসছিলো তা জানা ছিল না।
- এই মুহূর্তে Serve() ফাংশনে আমরা *gorm.DB এর একটি ইন্সট্যান্স তৈরি করবো (যার জন্য আমাদের “Go-bootcamp/pkg/connection” প্যাকেজটি ইমপোর্ট করতে হবে) এবং সেটা repositories/book.go এর BookDBInstance() ফাংশনে পাঠাবো । এজন্য আমাদের “Go-bootcamp/pkg/repositories” প্যাকেজটি ইমপোর্ট করতে হবে –
{
"bookname": "Sonar tori",
"author": "Rabindranath"
}
যদি আমাদের কোড ঠিকঠাক থাকে তাহলে Postman এ রেসপন্স আসবে “Book was updated successfully” এবং আমাদের ID = 1 বইয়ের ভ্যালু আপডেটেড হয়ে যাবে ।
রেফারেন্স হিসেবে নিচের ছবি টা দেখতে পারি –
এরপরে যদি আমরা আবার Read রিকোয়েস্ট পাঠাই তাহলে আপডেটেড বইটি দেখতে পাবো (localhost:9030/bookstore/book?bookID=1) –
[
{
"bookID": 1,
"bookname": "Sonar tori",
"author": "Rabindranath",
"publication": "Oxford Press"
}
]
[৮.৫.৪] Delete এর আদি-অন্ত
এবারে কাজ শুরু করব CRUD এর সর্বেশেষ ফাংশনালিটি, Delete নিয়ে :
- controllers/book.go এ –
- যতগুলো ফাংশনালিটি নিয়ে আমরা কাজ করেছি তার মধ্যে সবথেকে সহজ হবে Delete নিয়ে কাজ করা।
- সবার প্রথমে আমরা Update অংশের মতো URL থেকে প্যারামিটার টা বেড় করে নেব এবং পার্স করে তা ইন্টিজারে রূপান্তর করব –
tempBookID := e.Param("bookID")
bookID, err := strconv.ParseUint(tempBookID, 0, 0)
if err != nil {
return e.JSON(http.StatusBadRequest, "Invalid Data")
}
3. এরপর services/book.go এর GetBooks() মেথডে একটা রিকোয়েস্ট পাঠাবো, যেটার এরর পাঠানোর উপর ভিত্তি করে আমরা বুঝে যাবো যে ওই ID সম্বলিত বই ডাটাবেসে আছে কিনা।
_, err = BookService.GetBooks(uint(bookID))
if err != nil {
return e.JSON(http.StatusBadRequest, err.Error())
}
4. যদি থেকে থাকে তাহলে আমরা আবার services/book.go এর DeleteBook() মেথডে bookID পাঠিয়ে দেবো এবং রেসপন্সের অপেক্ষা করব। তাহলে controllers/book.go এর ফাইনাল কোডটি দাঁড়াচ্ছে –
controllers/book.go
func DeleteBook(e echo.Context) error {
tempBookID := e.Param("bookID")
bookID, err := strconv.ParseUint(tempBookID, 0, 0)
if err != nil {
return e.JSON(http.StatusBadRequest, "Invalid Data")
}
_, err = BookService.GetBooks(uint(bookID))
if err != nil {
return e.JSON(http.StatusBadRequest, err.Error())
}
if err := BookService.DeleteBook(uint(bookID)); err != nil {
return e.JSON(http.StatusInternalServerError, err.Error())
}
return e.JSON(http.StatusOK, "Book was deleted successfully")
}
- services/book.go এ –
5. services/book.go এর DeleteBook() মেথড থেকে repositories/book.go এর DeleteBook() মেথডে bookID পাস করে অপেক্ষায় থাকব ডাটাবেসের Delete অপারেশন রান করার।
6. যদি তা সফল না হয় তাহলে এরর রিটার্ন হবে এবং কন্ট্রোলারে “book deletion was unsuccesful” রেসপন্স পাঠানো হবে। অন্যথা কোনো এরর পাঠানো হবে না –
service/book.go
func (service *BookService) DeleteBook(bookID uint) error {
if err := service.repo.DeleteBook(bookID); err != nil {
return errors.New("book deletion was unsuccessful")
}
return nil
}
- repositories/book.go এ –
7. repositories/book.go এর DeleteBook() মেথড থেকে GORM এর Delete মেথড ব্যবহার করে, services/book.go থেকে প্রাপ্ত bookID অনুসারে উক্ত সারির সকল পরিবর্তিত ভ্যালু Delete হয়ে যাবে।
8. Delete না হয়ে থাকলে সার্ভিসে এরর রিটার্ন করবে এবং সে অনুযায়ী রেসপন্স জেনারেট হবে –
repositories/book.go
func (repo *bookRepo) DeleteBook(bookID uint) error {
var Book models.Book
if err := repo.db.
Where("id = ?", bookID).Delete(&Book).
Error; err != nil {
return err
}
return nil
}
POSTMAN এর ব্যবহার
“localhost:9030/bookstore/book/1” route এ DELETE রিকোয়েস্ট পাঠিয়ে আমরা DELETE ফাংশনালিটি ঠিকঠাক শেষ করতে পেরেছি কিনা তা চেক করতে পারি –
যদি আমাদের কোড ঠিকঠাক থাকে তাহলে Postman এ রেসপন্স আসবে “Book was deleted successfully” এবং আমাদের ID = 1 বইয়ের সব ভ্যালু Delete হয়ে যাবে ।
রেফারেন্স হিসেবে নিচের ছবি টা দেখতে পারি –
এরপরে যদি আমরা আবার Read রিকোয়েস্ট পাঠাই তাহলে Delete করা বইটি আর দেখতে পাবো না (localhost:9030/bookstore/book) –
[
{
"bookID": 2,
"bookname": "Killing Floor",
"author": "Lee Child",
"publication": "Oxford Press"
}
]