Architettura dei microservizi - SOA pratico
In questo capitolo, svilupperemo un'applicazione basata su CRUD con architettura SOA. Più avanti nei capitoli successivi, suddivideremo questo servizio in microservizio e impareremo la differenza fondamentale tra SOA e architettura a microservizi.
Configurazione e configurazione del sistema
In questa sezione, creeremo un'applicazione CRUD di esempio, che restituirà un oggetto JSON come risposta ogni volta che chiameremo il nostro servizio. Useremo il framework Jersey per sviluppare lo stesso. Di seguito sono riportati i passaggi per configurare l'ambiente di sistema locale.
Sviluppo di un'applicazione CRUD
Step 1- Useremo NetBeans come IDE di sviluppo. Scarica e installa l'ultima versione disponibile sul sito ufficiale di NetBeanshttps://netbeans.org/downloads/.
Step 2- Apri il tuo IDE NetBeans. Vai su "File -> Nuovo progetto". Viene visualizzata la seguente schermata. Scegli "Maven" come categoria e seleziona "Progetto da ArchType" come progetto e premi Avanti.
Questo scaricherà tutti i file jar richiesti per creare il tuo primo progetto Maven e il servizio Web RESTful.
Step 3- Premendo il pulsante Avanti nel passaggio precedente, viene visualizzata la seguente schermata. Qui, dovrai specificare l'archetipo Maven.
Nella casella di ricerca, cerca "Jersey-archType-Webapp (2.16)" e seleziona la casella di controllo "Mostra meno recenti".
Step 4- Dopo aver selezionato lo stesso, verrai reindirizzato alla schermata seguente. Seleziona il jar preferito dall'elenco e premi Avanti per continuare.
Step 5- In questo passaggio, è necessario fornire il nome del progetto e il relativo ID gruppo, nonché i dettagli del pacchetto. Dopo aver fornito tutte queste informazioni, premi Fine per continuare.
Step 6- Hai finito con la configurazione dell'area di lavoro. La directory del progetto sarà simile alla seguente.
Controlla la tua cartella "Dipendenze" e scoprirai che Maven ha scaricato automaticamente tutti i file jar richiesti per questo progetto.
Step 7- Il tuo spazio di lavoro è impostato e puoi iniziare con la codifica. Vai avanti e crea quattro classi e pacchetti come menzionato nello screenshot seguente. Puoi scoprire che MyResource.java è già stato creato da Maven, poiché Maven è abbastanza intelligente da rilevare che stai per creare il tuo servizio web.
Step 8 - Una volta terminato il passaggio precedente, costruiremo la nostra classe POJO che è UserProfile.java come segue.
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- Ora creeremo la nostra classe Database. Poiché questo fa parte del materiale didattico, non utilizzeremo alcun DB come database. Useremo una memoria Java incorporata per funzionare come memoria temporanea. Come puoi vedere nella seguente serie di codice, useremo MAP come nostro database. Tutte le operazioni del servizio web che eseguiremo, lavoreremo su questa MAP definita nella classe.
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- Ora costruiamo la nostra classe di servizio. Vai avanti e copia e incolla il seguente set di codice nella classe "ProfileService.java". Questa è la classe in cui dichiareremo tutti i metodi del nostro servizio web che devono essere esposti al mondo esterno. Dobbiamo creare un riferimento della nostra DatabaseClass in modo tale che il nostro database temporaneo sia accessibile in questa classe.
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 - In questo passaggio, creeremo la nostra classe di risorse che verrà collegata all'URL e verrà chiamato il servizio corrispondente.
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- Crea il progetto pulito ed eseguilo. Se tutto va bene, dovresti ottenere il seguente output nel browser, durante l'accessohttp://localhost:8080/UserProfile/webapi/Profile” URL.
Puoi vedere che diverse voci vengono popolate utilizzando la rappresentazione XML.
È possibile testare un metodo diverso utilizzando Postman applicando l'URL del metodo appropriato.
@GET method - Lo screenshot seguente mostra come ottenere il risultato desiderato per get request, che restituisce tutti i dettagli dell'utente.
@POST- La seguente richiesta può essere utilizzata per testare il nostro metodo Post. Notare come il proId è stato generato automaticamente.
@PUT- Questo metodo aggiornerà le voci. Lo screenshot seguente mostra come Jersey prende il proId dall'URL della richiesta e aggiorna la stessa risposta del profilo utente.
Allo stesso modo, puoi controllare altri metodi disponibili nei tuoi servizi web.
Nella sezione precedente, abbiamo sviluppato un servizio che esporrà la funzionalità CRUD. Ogni volta che proviamo a implementare questo servizio nella nostra applicazione, dobbiamo creare un client di questa applicazione e collegarlo alla nostra applicazione. In questo capitolo impareremo come costruire questa funzionalità utilizzando il concetto di Microservice. Di seguito è una rappresentazione schematica della nostra applicazione costruita utilizzando i passaggi precedenti.
L'attore dovrebbe essere il punto di ingresso del nostro servizio. In questo caso "ProfileResource.java" svolge la responsabilità di un attore. Questa classe chiamerà metodi diversi per eseguire diverse operazioni come aggiungere, aggiornare ed eliminare.
Decomposizione dell'applicazione CRUD
Secondo il principio principale del microservizio, dobbiamo avere un solo compito aziendale per ciascuno dei moduli, quindi un attore non dovrebbe essere responsabile di tutte e quattro le funzionalità CRUD. Considera il seguente esempio in cui abbiamo introdotto alcuni nuovi ruoli in modo tale che risulti concettualmente chiaro che Microservice è una rappresentazione architettonica di SOA.
"Utente principale" è l'utente che comunica con l '"Controller dell'applicazione" per soddisfare le proprie esigenze. “Application Controller” è colui che chiama semplicemente diversi “Resource Manager” a seconda della richiesta dell'utente finale. "Resource Manager" fa il lavoro che deve essere fatto. Diamo una rapida occhiata ai diversi ruoli delle diverse unità dell'applicazione.
End User/Main Users - Richieste di alcune risorse al controller dell'applicazione.
Application - Riceve la richiesta e la inoltra allo specifico Resource Manager.
Resource Manager - Fa il vero lavoro di aggiornamento, eliminazione e aggiunta di utenti.
Guarda come la responsabilità totale di una classe è distribuita tra le diverse altre classi.