2
respostas

Casos com JSON mais complexo do que o da aula

Como ficaria o modelo do Record se o JSON não fosse assim tão simples? E se ele tivesse listas e mais coisas dentro?

Eu to fazendo toda a formação consumindo a API do Spotify porque não quero simplesmente copiar e colar as coisas aqui.

1 - Me deparei com esse problema da API de uma música ser muito mais complexa. Como posso fazer isso? 2 - E se eu quiser obter só um dado bem simples do JSON, preciso fazer todo esse conjunto de coisas?

Um JSON "mais complexo" de exemplo abaixo:

Track: { "album" : { "album_type" : "single", "artists" : [ { "external_urls" : { "spotify" : "https://open.spotify.com/artist/15syP1FHsvvb7yOy6Jdcmm" }, "href" : "https://api.spotify.com/v1/artists/15syP1FHsvvb7yOy6Jdcmm", "id" : "15syP1FHsvvb7yOy6Jdcmm", "name" : "Soul Cream", "type" : "artist", "uri" : "spotify:artist:15syP1FHsvvb7yOy6Jdcmm" } ], "available_markets" : [ "AR", "BR", "XK" ], "external_urls" : { "spotify" : "https://open.spotify.com/album/14Sq2hix98eEdkhj9t80K4" }, "href" : "https://api.spotify.com/v1/albums/14Sq2hix98eEdkhj9t80K4", "id" : "14Sq2hix98eEdkhj9t80K4", "images" : [ { "height" : 640, "url" : "https://i.scdn.co/image/ab67616d0000b273c19644a2009e80903960624e", "width" : 640 }, { "height" : 300, "url" : "https://i.scdn.co/image/ab67616d00001e02c19644a2009e80903960624e", "width" : 300 }, { "height" : 64, "url" : "https://i.scdn.co/image/ab67616d00004851c19644a2009e80903960624e", "width" : 64 } ], "name" : "Samsara", "release_date" : "2023-10-02", "release_date_precision" : "day", "total_tracks" : 5, "type" : "album", "uri" : "spotify:album:14Sq2hix98eEdkhj9t80K4" }, "disc_number" : 1, "duration_ms" : 251786, "explicit" : false, "external_ids" : { "isrc" : "BCZ662300003" }, "external_urls" : { "spotify" : "https://open.spotify.com/track/6fjcBgBTMjPkKzg2kaFGpo" }, "href" : "https://api.spotify.com/v1/tracks/6fjcBgBTMjPkKzg2kaFGpo", "id" : "6fjcBgBTMjPkKzg2kaFGpo", "is_local" : false, "name" : "Eraserhead", "popularity" : 1, "preview_url" : "https://p.scdn.co/mp3-preview/ee8b6ea5c84044078ad6c5f3230e8b93cc46c4a7?cid=8cbb68ac910e4df9ab71e8fa74d1346e", "track_number" : 2, "type" : "track", "uri" : "spotify:track:6fjcBgBTMjPkKzg2kaFGpo" }

2 respostas

Eu pedi pro GPT formatar o seu Json, ficou assim:

{
  "Track": {
    "album": {
      "album_type": "single",
      "artists": [
        {
          "external_urls": {
            "spotify": "https://open.spotify.com/artist/15syP1FHsvvb7yOy6Jdcmm"
          },
          "href": "https://api.spotify.com/v1/artists/15syP1FHsvvb7yOy6Jdcmm",
          "id": "15syP1FHsvvb7yOy6Jdcmm",
          "name": "Soul Cream",
          "type": "artist",
          "uri": "spotify:artist:15syP1FHsvvb7yOy6Jdcmm"
        }
      ],
      "available_markets": ["AR", "BR", "XK"],
      "external_urls": {
        "spotify": "https://open.spotify.com/album/14Sq2hix98eEdkhj9t80K4"
      },
      "href": "https://api.spotify.com/v1/albums/14Sq2hix98eEdkhj9t80K4",
      "id": "14Sq2hix98eEdkhj9t80K4",
      "images": [
        {
          "height": 640,
          "url": "https://i.scdn.co/image/ab67616d0000b273c19644a2009e80903960624e",
          "width": 640
        },
        {
          "height": 300,
          "url": "https://i.scdn.co/image/ab67616d00001e02c19644a2009e80903960624e",
          "width": 300
        },
        {
          "height": 64,
          "url": "https://i.scdn.co/image/ab67616d00004851c19644a2009e80903960624e",
          "width": 64
        }
      ],
      "name": "Samsara",
      "release_date": "2023-10-02",
      "release_date_precision": "day",
      "total_tracks": 5,
      "type": "album",
      "uri": "spotify:album:14Sq2hix98eEdkhj9t80K4"
    },
    "disc_number": 1,
    "duration_ms": 251786,
    "explicit": false,
    "external_ids": {
      "isrc": "BCZ662300003"
    },
    "external_urls": {
      "spotify": "https://open.spotify.com/track/6fjcBgBTMjPkKzg2kaFGpo"
    },
    "href": "https://api.spotify.com/v1/tracks/6fjcBgBTMjPkKzg2kaFGpo",
    "id": "6fjcBgBTMjPkKzg2kaFGpo",
    "is_local": false,
    "name": "Eraserhead",
    "popularity": 1,
    "preview_url": "https://p.scdn.co/mp3-preview/ee8b6ea5c84044078ad6c5f3230e8b93cc46c4a7?cid=8cbb68ac910e4df9ab71e8fa74d1346e",
    "track_number": 2,
    "type": "track",
    "uri": "spotify:track:6fjcBgBTMjPkKzg2kaFGpo"
  }
}

Também deve dar pra formatar usando IDE.

Esse retorno da API representa uma música, certo? Uma boa parte dessas dados são dados do álbum, outra grande parte são dados dos artistas. Esse Json retorna uma objeto Track, esse objeto Track possui um objeto Album, esse objeto Album possui vários atributos, um deles é um lista de objetos Artist, que você também pode representar com um objeto na sua aplicação. Você não precisa capturar todos esses dados se você não quiser, dá pra escolher os dados que você quer usando as anotações.

Se a gente desmantelar esse Json Track e Album ficaria assim:

// Track
  "Track": {
    "disc_number": 1,
    "duration_ms": 251786,
    "explicit": false,
    "external_ids": {
      "isrc": "BCZ662300003"
    },
    "external_urls": {
      "spotify": "https://open.spotify.com/track/6fjcBgBTMjPkKzg2kaFGpo"
    },
    "href": "https://api.spotify.com/v1/tracks/6fjcBgBTMjPkKzg2kaFGpo",
    "id": "6fjcBgBTMjPkKzg2kaFGpo",
    "is_local": false,
    "name": "Eraserhead",
    "popularity": 1,
    "preview_url": "https://p.scdn.co/mp3-preview/ee8b6ea5c84044078ad6c5f3230e8b93cc46c4a7?cid=8cbb68ac910e4df9ab71e8fa74d1346e",
    "track_number": 2,
    "type": "track",
    "uri": "spotify:track:6fjcBgBTMjPkKzg2kaFGpo"
  }
}


// Album
    "album": {
      "album_type": "single",
      
      "available_markets": ["AR", "BR", "XK"],
      "external_urls": {
        "spotify": "https://open.spotify.com/album/14Sq2hix98eEdkhj9t80K4"
      },
      "href": "https://api.spotify.com/v1/albums/14Sq2hix98eEdkhj9t80K4",
      "id": "14Sq2hix98eEdkhj9t80K4",
      "images": [
        {
          "height": 640,
          "url": "https://i.scdn.co/image/ab67616d0000b273c19644a2009e80903960624e",
          "width": 640
        },
        {
          "height": 300,
          "url": "https://i.scdn.co/image/ab67616d00001e02c19644a2009e80903960624e",
          "width": 300
        },
        {
          "height": 64,
          "url": "https://i.scdn.co/image/ab67616d00004851c19644a2009e80903960624e",
          "width": 64
        }
      ],
      "name": "Samsara",
      "release_date": "2023-10-02",
      "release_date_precision": "day",
      "total_tracks": 5,
      "type": "album",
      "uri": "spotify:album:14Sq2hix98eEdkhj9t80K4"
    }
    
    
    // Artists
    {
    
     "artists": [
        {
          "external_urls": {
            "spotify": "https://open.spotify.com/artist/15syP1FHsvvb7yOy6Jdcmm"
          },
          "href": "https://api.spotify.com/v1/artists/15syP1FHsvvb7yOy6Jdcmm",
          "id": "15syP1FHsvvb7yOy6Jdcmm",
          "name": "Soul Cream",
          "type": "artist",
          "uri": "spotify:artist:15syP1FHsvvb7yOy6Jdcmm"
        }
      ]
    
}

Desde que você utilize a anotação @JsonIgnoreProperties, o Spring vai entender que ele só precisa mapear os atributos que você especificou nas anotações @JsonProperty, o que não tiver sido especificado o Spring simplesmente vai ignorar.

Aqui vai um exemplo do que dá pra fazer, você pode fazer capturando os dados que você quiser, essa é apenas uma demonstração do que dá pra fazer:

// Musica
@JsonIgnoreProperties(ignoreUnknown = true)
public record DadosMusica (
        @JsonProperty("id") 
        String id,
        
        @JsonProperty("name") 
        String nome,
        
        @JsonProperty("duration_ms") 
        Long duracaoEmMilissegundos,
        
        @JsonProperty("explicity")
        Boolean explicito,
        
        @JsonProperty("album")
        DadosAlbum album
        
    ) 
{}

// Album
@JsonIgnoreProperties(ignoreUnknown = true)
public record DadosAlbum (

        @JsonProperty("id") 
        String id,
        
        @JsonProperty("name") 
        String nome,
        
        // Esse atributo seria um forte candidato a virar um Enum
        @JsonProperty("album_type") 
        String tipoAlbum,
        
        @JsonProperty("release_date") @JsonForma(pattern = "yyyy-MM-dd")
        LocalDate dataLancamento,
        
        @JsonProperty("total_tracks")
        Integer totalFaixas,
        
        // É uma lista de artistas porque o Json retorna um array [] com vários objetos Artista
        @JsonProperty("artists")
        List<DadosArtista> artistas
        
    ) 
{}

// Artista
@JsonIgnoreProperties(ignoreUnknown = true)
public record DadosArtista(
        @JsonProperty("href") 
        String href,
        
        @JsonProperty("id") 
        Long id,
        
        @JsonProperty("name") 
        String nome,
        
        // Candidato a virar um Enum
        @JsonProperty("type") 
        String tipo,
        
        @JsonProperty("uri") 
        String uri
    )
{}

Digamos que você precisa extrair desse retorno somente aquela lista de artistas. Você já tem o DadosArtista pronto, mas ele não é uma coleção, então você poderia criar um DTO que recebe uma coleção de DadosArtista:

@JsonIgnoreProperties(ignoreUnknown = true)
public record DadosArtistas(
    
    @JsonProperty("artists")
    List<DadosArtista> artistas
    
){}

Espero que tenha ficado claro e tenha te ajudado. Me corrijam se eu ensinei errado kkk