I'm attempting to write a BlueSky Client in Java. The JSON the feed URLs provide is proving to be hard to parse by Jackson. I get this error when trying ObjectMapper.readValue(...).
Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `icg.engine.event.ingest.data.parsers.bluesky.BlueSkyFeed$Feed` from Array value (token `JsonToken.START_ARRAY`)
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 2, column: 11] (through reference chain: icg.engine.event.ingest.data.parsers.bluesky.BlueSkyFeed["feed"])
{
"feed": [
{
"post": {
"uri": "at://did:plc:4tbdzwidd7ol3o2y75dmahyv/app.bsky.feed.post/3lbry3snm2w2e",
"cid": "bafyreifa5c4g6ygyczrm7jshzgkla2tbgyqswm6lm5bpg6yhsl53nwbsna",
"author": {
"did": "did:plc:4tbdzwidd7ol3o2y75dmahyv",
"handle": "incanusthegrey.bsky.social",
"displayName": "Gandalf ",
"avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:4tbdzwidd7ol3o2y75dmahyv/bafkreihqgb7ruuozmc73crxwavpvdnnmroz6cwpwnfugzsvfd7ouj5fzlu@jpeg",
"viewer": {
"muted": false,
"blockedBy": false
},
"labels": [],
"createdAt": "2024-11-25T15:14:30.145Z"
},
"record": {
"$type": "app.bsky.feed.post",
"createdAt": "2024-11-25T16:49:13Z",
"text": "Hello world! I posted this via the API."
},
"replyCount": 0,
"repostCount": 0,
"likeCount": 0,
"quoteCount": 0,
"indexedAt": "2024-11-25T16:49:19.466Z",
"viewer": {
"threadMuted": false,
"embeddingDisabled": false
},
"labels": []
}
}
]
}
My POJO is (there are more for the other sub-objects but just posting the top ones for brevity)
public class BlueSkyFeed {
@JsonProperty("feed")
private Feed feed;
public Feed getFeed() {
return feed;
}
public void setFeed(Feed feed) {
this.feed = feed;
}
public static class Feed {
@JsonProperty("post")
public Post[] post;
public Post[] getPost() {
return post;
}
public void setPost(Post[] post) {
this.post = post;
}
}
public static class Post {
public String uri;
public String cid;
public Author author;
@JsonProperty("record")
public Record myrecord;
public int replyCount;
public int repostCount;
public int likeCount;
public int quoteCount;
public Date indexedAt;
public Viewer viewer;
public ArrayList<Object> labels;
public Embed embed;
}
}
As the error says, parse error at Feed, token of START_ARRAY at line 2
So, look at line 2
"feed": [
This is the start of an array ✅
With enough experience in Jackson / JSON (or using the tool posted above in the comments), this would not represent an object class. You must use a Collection subclass or Array.
Look at your code. You don't have Feed[] feed;
and therefore, you get a parser exception...
You do not need JSONProperty annotations on fields of the same name.
You should add default or all-arg constructors to each class, or look into record
classes / Lombok. Or switch to Kotlin
As the second comment implies, write unit tests with mocked responses to test your parsing logic before you start getting rate limited and/or banned from BlueSky API (Twitter at least, has that)
You could also just generate the whole client with all the types in almost any language or framework with one cli command...
https://github.com/bluesky-social/bsky-docs/tree/main/atproto-openapi-types/spec