Na wstępie chciałbym zaznaczyć, wiem że do użycia mikoserwisów powinienem mieć dobry powód i że bardzo prawdopodobne jest, że calkowicie nie potrzebuje ich używać. Niemniej jednak, w celach edukacyjnych chciałbym po godzinach napisać aplikację opartą o mikoserwisy.
No i mam w związku z tym kilka pytań. Powiedzmy, że jest to jakaś aplikacja typu to-do list, w przypadku standardowego podejścia, miałbym jedną bazę danych a w niej encje powiązane mniej więcej w ten sposób (zapis w postaci Javowych klas, ale myślę że każdy rozumie o co chodzi)
@Entity
public class User {
@Id
private Long id;
private String username;
@OneToMany
private List<Task> tasks;
}
@Entity
public class Task {
@Id
private Long id;
private String description;
@ManyToOne
private User assignedTo;
}
Rozumiem, że w przypadku architektury opartej o mikroserwisy, zarówno mój UserService i TaskService będzie korzystać z innych baz danych. Relacje więc nie mają tutaj sensu, powyższe encje wyglądają więc tak:
@Entity
public class User {
@Id
private Long id;
private String username;
private List<String> taskIds;
}
@Entity
public class Task {
@Id
private Long id;
private String description;
private String assignedUserId;
}
Czy moze, powstaje trzeci mikorserwis - UserTaskService, a struktura danych prezentuje się wtedy w ten sposób
@Entity
public class User {
@Id
private Long id;
private String username;
}
@Entity
public class Task {
@Id
private Long id;
private String description;
}
@Entity
public class UserTask {
@Id
private Long id;
private Long userId;
private Long taskId;
}
Niezależnie od tego która opcja jest poprawna, powstaje pytanie jak wygląda flow tworzenia Taska. W pierwszym podejściu serwisy Task i User są dość mocno powiązane, np. TaskService musi wywołać UserService by zaktualizować listę tasków Usera. Dodatkowo, tych parametrów Usera na pewno będzie więcej, więc zaraz się okaze że prawie każdy serwis jest powiązany z Userem. Drugie podejście wydaje się więc nieco bardziej na miejscu, jednak już dla prostego case mamy 3 różne mikroserwisy. Trzecia opcja o jakiej myślałem to MQ, czyli zarówno TaskService i UserService nasłuchują na CreateTaskMessage, powodować to może jednak niespójność danych, w jednym serwisie Task może już być przypisany do Usera, a w drugim nie. No i co jeżeli jakaś potencjalna walidacja w jednym z tych serwisów przejdzie, a w drugim nie?
No i drugie pytanie - DTOsy. Czy to na frontendzie, czy to w innych serwisach, w pewnym momencie trzeba będzie przekazać konkretne dane, a nie tylko id, z jednego serwisu do drugiego. Jak to rozwiązać w świecie mikroserwisów? Generować model na podstawie Swaggera? Jeżeli całość tworzona jest pod jednym parentem Mavenowym, to można wrzucić dto w shared module, ale to chyba trochę przeczy całej idei?