สถาปัตยกรรม Microservice - SOA แบบ Hands-On
ในบทนี้เราจะพัฒนาแอปพลิเคชันที่ใช้ CRUD ด้วยสถาปัตยกรรม SOA ต่อไปในบทต่อ ๆ ไปเราจะแยกบริการนี้ออกเป็นไมโครเซอร์วิสและเราจะเรียนรู้ความแตกต่างพื้นฐานระหว่างสถาปัตยกรรม SOA และไมโครเซอร์วิส
การกำหนดค่าระบบและการตั้งค่า
ในส่วนนี้เราจะสร้างแอปพลิเคชัน CRUD ตัวอย่างซึ่งจะส่งคืนออบเจ็กต์ JSON เป็นการตอบสนองทุกครั้งที่เราเรียกใช้บริการของเรา เราจะใช้เจอร์ซีกรอบในการพัฒนาเดียวกัน ต่อไปนี้เป็นขั้นตอนในการตั้งค่าสภาพแวดล้อมระบบโลคัลของคุณ
การพัฒนาแอปพลิเคชัน CRUD
Step 1- เราจะใช้ NetBeans เป็น IDE ในการพัฒนา โปรดดาวน์โหลดและติดตั้งเวอร์ชันล่าสุดบนเว็บไซต์ทางการของ NetBeanshttps://netbeans.org/downloads/.
Step 2- เปิด NetBeans IDE ของคุณ ไปที่“ ไฟล์ -> โครงการใหม่” ภาพหน้าจอต่อไปนี้จะปรากฏขึ้น เลือก“ Maven” เป็นหมวดหมู่และเลือก“ Project from ArchType” เป็นโปรเจ็กต์แล้วกด Next
สิ่งนี้จะดาวน์โหลดไฟล์ jar ที่จำเป็นทั้งหมดเพื่อสร้างโปรเจ็กต์ Maven และ RESTful Web Service ครั้งแรกของคุณ
Step 3- ในการกดปุ่ม Next ในขั้นตอนก่อนหน้านี้ภาพหน้าจอต่อไปนี้จะปรากฏขึ้น ที่นี่คุณจะต้องระบุ Maven Archetype
ในช่องค้นหาให้ค้นหา“ Jersey-archType-Webapp (2.16)” แล้วเลือกช่องทำเครื่องหมาย“ Show Older”
Step 4- เมื่อคุณเลือกแบบเดียวกันคุณจะถูกนำไปยังหน้าจอต่อไปนี้ เลือกโถที่ต้องการจากรายการและกด Next เพื่อดำเนินการต่อ
Step 5- ในขั้นตอนนี้คุณต้องระบุชื่อโครงการของคุณและรหัสกลุ่มของคุณรวมถึงรายละเอียดแพ็คเกจ หลังจากให้ข้อมูลทั้งหมดแล้วให้กด Finish เพื่อดำเนินการต่อ
Step 6- คุณตั้งค่าพื้นที่ทำงานเสร็จแล้ว ไดเรกทอรีโครงการจะมีลักษณะดังต่อไปนี้
ตรวจสอบโฟลเดอร์ "Dependencies" ของคุณและคุณจะพบว่า Maven ได้ดาวน์โหลดไฟล์ jar ที่จำเป็นทั้งหมดสำหรับโครงการนี้โดยอัตโนมัติ
Step 7- พื้นที่ทำงานของคุณได้รับการตั้งค่าและคุณสามารถเริ่มต้นด้วยการเขียนโค้ดได้ สร้างคลาสและแพ็กเกจสี่คลาสตามที่ระบุไว้ในภาพหน้าจอต่อไปนี้ คุณจะพบว่า MyResource.java สร้างขึ้นโดย Maven แล้วเนื่องจาก Maven ฉลาดพอที่จะตรวจพบว่าคุณกำลังจะสร้างบริการเว็บของคุณเอง
Step 8 - เมื่อทำตามขั้นตอนข้างต้นเสร็จแล้วเราจะสร้างคลาส POJO ของเราที่เป็น UserProfile.java ดังต่อไปนี้
package com.tutorialspoint.userprofile.Model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class UserProfile {
private long ProId;
private String FName;
private String LName;
private String Add;
public UserProfile(){}
public UserProfile(long Proid, String Fname, String Lname,String Add) {
this.ProId = Proid;
this.FName = Fname;
this.LName = Lname;
this.Add = Add;
}
public long getProId() {
return ProId;
}
public void setProId(long ProId) {
this.ProId = ProId;
}
public String getFName() {
return FName;
}
public void setFName(String FName) {
this.FName = FName;
}
public String getLName() {
return LName;
}
public void setLName(String LName) {
this.LName = LName;
}
public String getAdd() {
return Add;
}
public void setAdd(String Add) {
this.Add = Add;
}
}
Step 9- ตอนนี้เราจะสร้างคลาสฐานข้อมูลของเรา เนื่องจากนี่เป็นส่วนหนึ่งของสื่อการเรียนรู้เราจะไม่ใช้ฐานข้อมูลใด ๆ เป็นฐานข้อมูลของเรา เราจะใช้หน่วยความจำ Java ในตัวเพื่อทำงานเป็นหน่วยความจำชั่วคราวของเรา ดังที่คุณเห็นในชุดรหัสต่อไปนี้เราจะใช้ MAP เป็นฐานข้อมูลของเรา การดำเนินการบริการเว็บทั้งหมดที่เราดำเนินการเราจะทำงานบน MAP นี้ที่กำหนดไว้ในคลาส
package com.tutorialspoint.userprofile.DAO;
import com.tutorialspoint.userprofile.Model.UserProfile;
import java.util.HashMap;
import java.util.Map;
public class DatabaseClass {
private static Map<Long,UserProfile> messages = new HashMap<Long,UserProfile>();
public static Map<Long,UserProfile> getUsers() {
return messages;
// Each time this method will return entire map as an instance of database
}
}
Step 10- ตอนนี้ให้เราสร้างคลาสบริการของเรา คัดลอกและวางชุดรหัสต่อไปนี้ในคลาส“ ProfileService.java” นี่คือคลาสที่เราจะประกาศวิธีการบริการเว็บทั้งหมดของเราที่จะเปิดเผยต่อโลกภายนอก เราจำเป็นต้องสร้างการอ้างอิงของ DatabaseClass ของเราเพื่อให้สามารถเข้าถึงฐานข้อมูลชั่วคราวของเราได้ในคลาสนี้
package com.tutorialspoint.userprofile.service;
import com.tutorialspoint.userprofile.DAO.DatabaseClass;
import com.tutorialspoint.userprofile.Model.UserProfile;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ProfileService {
private Map<Long,UserProfile> Userprofiles = DatabaseClass.getUsers();
// Creating some predefine profile and populating the same in the map
public ProfileService() {
UserProfile m1 = new UserProfile(1L,"Tutorials1","Point1","TutorialsPoint.com");
UserProfile m2 = new UserProfile(2L,"Tutorials2","Point2","TutorialsPoint.com2");
UserProfile m3 = new UserProfile(3L,"Tutorials3","Point3","TutorialsPoint.com3");
UserProfile m4 = new UserProfile(4L,"Tutorials4","Point4","TutorialsPoint.com4");
Userprofiles.put(1L, m1);
Userprofiles.put(2L, m2);
Userprofiles.put(1L, m3);
Userprofiles.put(2L, m4);
}
//Method to fetch all profile
public List<UserProfile> getAllProfile() {
List<UserProfile> list = new ArrayList<UserProfile>(Userprofiles.values());
return list;
} // Method to fetch only one profile depending on the ID provided
public UserProfile getProfile(long id) {
return Userprofiles.get(id);
} //Method to add profile
public UserProfile addProfile(UserProfile UserProfile) {
UserProfile.setProId(Userprofiles.size()+1);
Userprofiles.put(UserProfile.getProId(), UserProfile);
return UserProfile;
} //method to update Profile
public UserProfile UpdateProfile(UserProfile UserProfile) {
if(UserProfile.getProId()<=0) {
return null;
} else {
Userprofiles.put(UserProfile.getProId(), UserProfile);
return UserProfile;
}
} //method to delete profile
public void RemoveProfile(long Id) {
Userprofiles.remove(Id);
}
}
Step 11 - ในขั้นตอนนี้เราจะสร้างคลาส Resource ของเราที่จะเชื่อมโยงกับ URL และจะเรียกใช้บริการที่เกี่ยวข้อง
package com.tutorialspoint.userprofile.Resource;
import com.tutorialspoint.userprofile.Model.UserProfile;
import com.tutorialspoint.userprofile.service.ProfileService;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/Profile")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public class ProfileResource {
ProfileService messageService = new ProfileService();
@GET
public List<UserProfile> getProfile() {
return messageService.getAllProfile();
}
@GET
@Path("/{ProID}")
public UserProfile getProfile(@PathParam("ProID")long Id) {
return messageService.getProfile(Id);
}
@POST
public UserProfile addProfile(UserProfile profile) {
return messageService.addProfile(profile);
}
@PUT
@Path("/{proID}")
public UserProfile UpdateProfile(@PathParam("proID")long Id,UserProfile UserProfile) {
UserProfile.setProId(Id);
return messageService.UpdateProfile(UserProfile);
}
@DELETE
@Path("/{ProID}")
public void deleteProfile(@PathParam("ProID")long Id) {
messageService.RemoveProfile(Id);
}
}
Step 12- ทำความสะอาดสร้างโครงการและเรียกใช้ หากทุกอย่างเป็นไปด้วยดีคุณควรได้รับผลลัพธ์ต่อไปนี้ในเบราว์เซอร์ขณะเข้าถึงhttp://localhost:8080/UserProfile/webapi/Profile” URL
คุณสามารถดูรายการต่างๆที่สร้างขึ้นโดยใช้การแสดง XML
วิธีการต่างๆสามารถทดสอบได้โดยใช้บุรุษไปรษณีย์โดยใช้ URL วิธีการที่เหมาะสม
@GET method - ภาพหน้าจอต่อไปนี้แสดงให้เห็นว่าเราจะได้ผลลัพธ์ที่ต้องการสำหรับคำขอได้อย่างไรซึ่งจะแสดงรายละเอียดผู้ใช้ทั้งหมด
@POST- สามารถใช้คำขอต่อไปนี้เพื่อทดสอบวิธีการโพสต์ของเรา สังเกตว่า proId ถูกสร้างขึ้นโดยอัตโนมัติอย่างไร
@PUT- วิธีนี้จะอัปเดตรายการ ภาพหน้าจอต่อไปนี้แสดงให้เห็นว่า Jersey ใช้ proId จาก URL คำขอและอัปเดตการตอบกลับโปรไฟล์ผู้ใช้เดียวกันได้อย่างไร
ในทำนองเดียวกันคุณสามารถตรวจสอบวิธีการอื่น ๆ ที่มีอยู่ในบริการบนเว็บของคุณ
ในส่วนก่อนหน้านี้เราได้พัฒนาบริการหนึ่งซึ่งจะแสดงฟังก์ชัน CRUD เมื่อใดก็ตามที่เราพยายามใช้บริการนี้ในแอปพลิเคชันของเราเราจำเป็นต้องสร้างไคลเอนต์ของแอปพลิเคชันนี้และแนบเข้ากับแอปพลิเคชันของเรา ในบทนี้เราจะเรียนรู้วิธีการสร้างฟังก์ชันนี้โดยใช้แนวคิดของ Microservice ต่อไปนี้คือการแสดงแผนผังของแอปพลิเคชันของเราที่สร้างขึ้นโดยใช้ขั้นตอนข้างต้น
นักแสดงควรเป็นจุดเริ่มต้นของบริการของเรา ในกรณีนี้“ ProfileResource.java” จะเป็นหน้าที่ของนักแสดง คลาสนี้จะเรียกวิธีการที่แตกต่างกันเพื่อดำเนินการที่แตกต่างกันเช่นเพิ่มอัปเดตและลบ
การสลายตัวของแอปพลิเคชัน CRUD
ตามหลักการสำคัญของ microservice เราจำเป็นต้องมีงานทางธุรกิจเพียงอย่างเดียวสำหรับแต่ละโมดูลดังนั้นนักแสดงคนหนึ่งจึงไม่ควรรับผิดชอบฟังก์ชัน CRUD ทั้งสี่อย่าง ลองพิจารณาตัวอย่างต่อไปนี้ที่เราได้แนะนำบทบาทใหม่บางอย่างเพื่อให้คุณเข้าใจได้อย่างชัดเจนว่า Microservice เป็นตัวแทนทางสถาปัตยกรรมของ SOA
“ ผู้ใช้หลัก” คือผู้ใช้ที่สื่อสารกับ“ Application Controller” เพื่อตอบสนองความต้องการ "ตัวควบคุมแอปพลิเคชัน" คือผู้ที่เรียกว่า "ผู้จัดการทรัพยากร" ที่แตกต่างกันขึ้นอยู่กับคำขอจากผู้ใช้ปลายทาง “ ผู้จัดการทรัพยากร” ทำงานที่จำเป็นต้องทำ มาดูบทบาทต่างๆของหน่วยต่างๆของแอปพลิเคชันกันอย่างรวดเร็ว
End User/Main Users - ขอทรัพยากรบางอย่างไปยัง Application Controller
Application - รับคำขอและส่งต่อสิ่งเดียวกันกับผู้จัดการทรัพยากรเฉพาะ
Resource Manager - งานอัปเดตลบและเพิ่มผู้ใช้จริงหรือไม่
ดูว่าความรับผิดชอบทั้งหมดของชั้นเรียนหนึ่งถูกกระจายไปยังชั้นเรียนอื่น ๆ อย่างไร