Mam serwer napisany w Springu i Kotlinie wystawiający jeden endpoint - /graphql oraz frontend Angularowy który ten endpoint wykorzystuje. W przypadku wszelkiego rodzaju query, to się sprawdziło świetnie, aczkolwiek zastanawiam się co robić w przypadku mutations, a dokładnie - co zwracać i co przekazywać.

Dla tego przykładu weźmy dwie operacje,

  • addPost - wymaga 1 parametru, postContent: String
  • addComment - wymaga 2 parametrów, commentContent: String oraz postId: String

W jednym i drugim przypadku tak naprawdę nie potrzebuje informacji zwrotnej innej niż HttpStatus 201, jednak w przypadku GraphQLa wszystkie operację kończą się Http 200 + data bądź error w odpowiedzi. No i pytanie jak to rozegrać:

Po 1, czy dla każdej operacji faktycznie tworzyć osobne dto? Nawet w przypadku funkcji z 1 parametrem? A co z 2, 3, n parametrami? Kiedy tworzyć DTO a kiedy nie zawracać sobie tym głowy? Generalnie, każdy taki dto oznacza input w schema.graphqls

input CreatePostRequest {
    content: String!
}

Dodatkowo, analogiczna klasa po stronie serwera

data class CreatePostRequest(val content: String)

Po stronie frontendu nie jest to konieczne, mogę zrobić coś takiego jak niżej i przekazać Stringa, albo mogę iść za ciosem i tam również stworzyć odpowiednią strukturę

    return this.apollo.watchQuery({
      query,
      variables: {
        input: {
          content: 'lorem ipsum'
        }
      }
    }).valueChanges.pipe...

Po 2, co zwracać z takich usług? Po stronie frontu po np. dodaniu posta, chcę oczywiście go wyświetlić, mogę więc

  • zwrócić jakiś generyczny obiekt odpowiedzi, informujący tylko o sukcesie bądz niepowodzeniu operacji i następnie odświeżyć listę postów, czyli zawołąć coś w rodzaju getAllPosts
  • dla każdej operacji stworzyć osobny typ odpowiedzi i po zakończonej operacji pobierać tylko utworzony post po id i dorzucić go do listy pozostałych postów
data class CreatePostResponse(val postId: String)

oraz

type CreatePostResponse {
        postId: String!
}

oraz

export interface CreatePostResponse {
        postId: string;
}
  • z każdej operacji zwracać dokładnie to co zostało stworzone, czyli np. cale PostDto, w efekcie po prostu doklejam ten post do reszty jak w punkcie wyżej, ale nie muszę dodatkowo wywoływać innych usług