Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ This file provides context for AI coding agents working in this repository.

- **Group ID:** `se.michaelthelin.spotify`
- **Artifact ID:** `spotify-web-api-java`
- **Current Version:** `10.0.0-RC1`
- **Build Tool:** Maven (`pom.xml`)
- **Java Version:** 17+
- **Java Version:** compiled with `--release 9`; CI builds on JDK 17 and 25

## Repository Structure

Expand Down Expand Up @@ -49,7 +48,6 @@ Create `src/main/java/se/michaelthelin/spotify/requests/data/<category>/<Endpoin

Key patterns:
- Extend `AbstractDataRequest<ReturnType>` (or `AbstractDataPagingRequest` for paginated results).
- Annotate with `@JsonDeserialize(builder = <ClassName>.Builder.class)`.
- Implement `execute()` which calls `getJson()`, `postJson()`, `putJson()`, or `deleteJson()` as appropriate.
- Add a `static final class Builder` with:
- Path parameters set via `setPathParameter("key", value)`
Expand Down Expand Up @@ -86,6 +84,19 @@ Extend `AbstractDataTest<ReturnType>`. Tests should:

Common test constants are in `ITest.java` (e.g., `ITest.NAME`, `ITest.ID_PLAYLIST`, `ITest.PUBLIC`).

### 5. Add an example and index it

Create `examples/.../<EndpointName>Example.java` and link it from the example index in `README.md`.
Mark the link with ⚠️ if the request class carries `@Deprecated`.

`./ci/check-docs.py` enforces all of this and runs in CI.
It checks that every `SpotifyApi` method has an example, that example file names match their request class, that the README index is complete and its ⚠️ markers match the code, that each request's verb and path exist in `spec/openapi.yaml` with matching deprecation, and that every current-API name written in `MIGRATION.md` still resolves.

### Renaming or removing public API

Record it in `MIGRATION.md` under the relevant `#### ` heading.
Names that no longer exist have to sit in a table column whose header contains "v9", or inside a code fence under a `// v9` marker, otherwise the docs check reports them as stale.

## Building and Testing

```bash
Expand All @@ -104,6 +115,10 @@ mvn test -Dtest="*Playlist*"

## Key Conventions

- **Model objects are deserialized reflectively** by the shared Gson in
`model_objects/ModelObjectGson.java`, so a new field needs no parsing code.
Add `@SerializedName` only when the wire name is not the snake_case form of the field,
and add a type adapter only for a shape reflection cannot express.
- **Trailing underscores** on Java-reserved words: e.g., `public_` for the `public` field.
- **Assertions** in tests are imported from both JUnit 5 (`org.junit.jupiter.api.Assertions`) and the project's own `se.michaelthelin.spotify.Assertions`.
- **Nullable fields** from the API should be tested with `assertNull(...)` when the fixture returns `null`.
Expand Down
27 changes: 27 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,31 @@ There is no replacement.
| `Track` | `getAvailableMarkets()`, `getLinkedFrom()`, `getPopularity()` |
| `TrackSimplified` | `getAvailableMarkets()`, `getLinkedFrom()` |

#### Removed classes

Nothing in the library referred to these any more, in most cases because 10.0.0 dropped the getter that used them.

| v9 type | Why it went |
|---|---|
| `AlbumGroup` | backed `AlbumSimplified.getAlbumGroup()`, which the specification deprecated |
| `ProductType` | backed the user product getter, which the specification deprecated |
| `PlaylistTrackPosition` | never referenced by any request or model object |
| `Paging.JsonUtil`, `PagingCursorbased.JsonUtil` | resolved their type argument to a parameterized type rather than a class, so instantiating either always threw |

A `Paging` object is built through the JsonUtil of the type it contains, which is how every request already built one.
The `IModelObject` array helper that took an explicit element class is gone as well, having had no callers.

#### New getters and model objects

`Album` and `AlbumSimplified` gained `getTotalTracks()`, `AlbumSimplified` also `getIsPlayable()`, `Episode` and `EpisodeSimplified` `getHtmlDescription()`, `User` `getAccountId()` and `getExplicitContent()`, and `SearchResult` `getAudiobooks()`.

Audiobooks and chapters are new: `Audiobook`, `AudiobookSimplified`, `Chapter`, `ChapterSimplified`, `ChapterRestriction`, `Author` and `Narrator`.
`ExplicitContentSettings` backs the new `User.getExplicitContent()`.

Three getters that always returned `null` in 9.4.0 now return a value, because the parser was reading a key the API does not send.
`AudioAnalysisTrack` fixes `getWindowSeconds()` and `getEndOfFadeIn()`, and `AudioAnalysisSection` fixes `getMode()`.
Code that null-checked them will now take the other branch.

Seven interfaces were extracted so that full and simplified objects can be handled through one type: `IAlbum`, `IArtist`, `IEpisode`, `IPlaylist`, `IShow`, `ITrack` and `IHasTotal`.

### New in 10.0.0
Expand Down Expand Up @@ -204,6 +222,15 @@ Playlist items on the `/items` path, replacing the `/tracks` path:

And `getAvailableMarkets` ⚠️ for `GET /markets`.

### Deserialization

Model objects are deserialized reflectively by Gson.
The Jackson annotations every model carried are gone, along with the Jackson dependency itself, because nothing in the library ever constructed an ObjectMapper.

This only affects you if you fed these model classes into your own ObjectMapper.
The `@JsonDeserialize` annotations gave you builder-based deserialization for free, and you now have to configure that yourself.
Nothing changes for code that goes through the library.

### Deprecations

49 of the 114 request builders carry `@Deprecated`, up from 1 in 9.4.0.
Expand Down
11 changes: 6 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,6 @@
<version>6.1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.22.2</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
Expand Down Expand Up @@ -200,6 +195,11 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.12.0</version>
<configuration>
<!-- accessors and builder setters in model_objects carry no prose of their own,
so only broken syntax and dead references should be reported -->
<doclint>all,-missing</doclint>
</configuration>
</plugin>
</plugins>
</build>
Expand Down Expand Up @@ -261,6 +261,7 @@
</execution>
</executions>
<configuration>
<doclint>all,-missing</doclint>
<outputDirectory>${project.basedir}/</outputDirectory>
</configuration>
</plugin>
Expand Down
54 changes: 0 additions & 54 deletions src/main/java/se/michaelthelin/spotify/enums/AlbumGroup.java

This file was deleted.

56 changes: 0 additions & 56 deletions src/main/java/se/michaelthelin/spotify/enums/ProductType.java

This file was deleted.

Loading
Loading