Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate ParselyMetadata and ParselyVideoMetadata to Kotlin. Improve API. #96

Merged
merged 12 commits into from
Dec 13, 2023

Conversation

wzieba
Copy link
Collaborator

@wzieba wzieba commented Nov 29, 2023

Description

This PR migrates ParselyMetadata and ParselyVideoMetadata to Kotlin and improves its API so it's easier to use - especially for clients, which use Kotlin.

Tests

There's no need to manually test this change. Unit tests should be fine.

BREAKING CHANGE: `toMap` were previously exposed to SDK consumers, but from SDK point of view, this was not necessary. To simplify the contract, those method are moved to be internal only. Also, the properties don't have to be `public` for the same reason.
`int` cannot be `null`, and `videoId` is annotated as `NonNull`
BREAKING CHANGE: instead of `java.utils.Calendar`, consumers now have to provide timestamp (in milliseconds) of publication date.
Copy link

codecov bot commented Nov 29, 2023

Codecov Report

Attention: 11 lines in your changes are missing coverage. Please review.

Comparison is base (ee8614e) 68.24% compared to head (67a755b) 70.52%.

Files Patch % Lines
...com/parsely/parselyandroid/ParselyVideoMetadata.kt 27.27% 6 Missing and 2 partials ⚠️
...java/com/parsely/parselyandroid/ParselyMetadata.kt 87.50% 0 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #96      +/-   ##
==========================================
+ Coverage   68.24%   70.52%   +2.27%     
==========================================
  Files          16       16              
  Lines         359      363       +4     
  Branches       52       53       +1     
==========================================
+ Hits          245      256      +11     
+ Misses         97       92       -5     
+ Partials       17       15       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

There's no need to force API consumers to use `ArrayList` - any `List`
will be just fine.
Comment on lines 21 to 20
Calendar pubDate;
long publicationDateMilliseconds;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd appreciate feedback on this change. I don't like introducing a breaking change to the library, but at the same time, I would rather not force users to use java.util.Calendar API - there's no need to attach to this specific class to share a moment in time.

I've decided to propose a simple, API-agnostic, straightforward and universal long property. The consequence of this is that user can now easily provide an incorrect value (e.g. timestamp in seconds), but I sense that it's not that likely (name of the property) and simpler API has more value. WDYT?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you elaborate on why using Calendar would be undesirable - besides the fact that it may not be the particular API the clients are using?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The concern about different APIs used by the clients is the main one, but Calendar also feels heavier than what we need from this field, which is passing a timestamp.

But, as the majority of the usage is probably passing Calendar.getInstance() here, maybe it's not a big deal and backward compatibility and safer API design is better? I'm not sure now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion, in most cases using a type is better than not having a type at all. One obvious exception to that is when using a specific type requires the clients to add a new dependency. However, I believe java.util.Calendar is available without any external dependencies, so I don't see any issues about that.

Even if the type we choose is not exactly the type the clients would like to use, they can always convert to it on a need to basis as long as it is properly documented. In this case, Calendar is a well known and properly documented class, so I think it's a very good candidate to be used in external facing APIs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right - Calendar is a well-known and available dependency for every client. I agree it's easy to convert from any other API. Thank you for sharing your thoughts! - I brought back Calendar in 67a755b

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! 🙇‍♂️

In Java implementation, `pubDate` was `@Nullable` so there's no reason
to change it in Kotlin implementation.
Comment on lines 24 to 30
private val authors: List<String>? = null,
@JvmField internal val link: String? = null,
private val section: String? = null,
private val tags: List<String>? = null,
private val thumbUrl: String? = null,
private val title: String? = null,
private val publicationDateMilliseconds: Long? = null
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of this, I was exploring introducing a builder pattern, so Java clients won't have to provide null in place of nullable fields.

I decided not doing it, as it'd deviate more from the original implementation, making addressing the breaking change more difficult. Furthermore, it'd be much different than iOS API. So I think, the default values for arguments will be just fine - making the API nicer for Kotlin users and not changing it for Java users.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I know, using Builder pattern would mean that we're adding to the API not changing it. We'd still have the ParselyMetadata without any breaking changes - but there would also be a ParselyMetadataBuilder which returns ParselyMetadata when we call .build() on it.

That's all to say that, if Builder pattern is something you'd like to utilize, I don't think it conflicts with the current implementation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true - thanks. I've tunneled vision on constructor OR builder, but there's no reason to not introduce builder separately from the constructor. Still, for now, I'd leave this as it is and keep the builder for possible enhancement in the future.

@wzieba wzieba marked this pull request as ready for review December 12, 2023 16:20
@wzieba wzieba requested a review from oguzkocer December 12, 2023 16:21
* internet (i.e. app-only content) or if the customer is using an "in-pixel" integration.
* Otherwise, metadata will be gathered by Parse.ly's crawling infrastructure.
*/
open class ParselyMetadata
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I always get a little worried when I see open keyword, but I guess this is keeping the current design - so it's all good 😅

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True 😃 but yes, that's intentional.

Copy link
Collaborator

@oguzkocer oguzkocer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wzieba I left a couple replies to your line comments - but I don't have much else to add as this is a very straightforward PR. I'll mark this as approved once the conversations are resolved.

@wzieba wzieba requested a review from oguzkocer December 13, 2023 11:47
@wzieba wzieba merged commit 7504512 into main Dec 13, 2023
2 checks passed
@wzieba wzieba deleted the issue/migrate_metadata_to_kotlin branch December 13, 2023 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants