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

Add kotlinx serialization extension methods for HttpFetcher #615

Merged

Conversation

dead8309
Copy link
Contributor

No description provided.

@bitspittle
Copy link
Collaborator

The API looks great!

One thing I am now realizing is something is still missing: in addition to window.http.*, we also have window.api.*, which is basically like window.http but designed for use with server API routes. (In fact, ApiFetcher was first but I added HttpFetcher later since it was more generally applicable)

So here's the question...

Do we create a single serialization module, where covers both HttpFetcher and ApiFetcher extensions can live together? Or do we have a separate module for each one?

I'm actually leaning to using one module for both, because I think in practice it's unlikely for HttpFetcher and its extension methods ever to get upstreamed to JetBrains, so instead we can just create a single module which is simple and convenient for Kobweb users (and we can always break it up later if we need to).

But if we do that, it demands a different name. Maybe just kobwebx-core-serialization or something like that? (Since ApiFetcher lives in kobweb-core)

The two choices that I'm seeing:

  • One module, which encompasses both HttpFetcher and ApiFetcher, but it needs a different name at that point.
  • Two modules, one for browser, and the other for core. And the core module has an api dependency on the browser module. We'd still need a new name for the ApiFetcher one.

Any opinions?

@dead8309
Copy link
Contributor Author

dead8309 commented Oct 12, 2024

I agree, I'm also leaning towards going with a single module approach. It will simplify things for Kobweb users and as you mentioned, we can always split it later if we need to.

For the internal structure, we can organize the HttpFetcher and ApiFetcher related code into separate packages within the module.

Do you have any thoughts on how we should proceed with implementing this? Should I start by outlining the internal structure of the new module?

As for the name of the module maybe one of kobwebx-core-serialization ,kobwebx-serialization-extensions. It's upto you

@dead8309 dead8309 changed the base branch from main to 0.19.3 October 12, 2024 10:06
@dead8309
Copy link
Contributor Author

Sorry! Skipped the Latest branch part in Contributing file

@bitspittle
Copy link
Collaborator

For the internal structure, we can organize the HttpFetcher and ApiFetcher related code into separate packages within the module.

Do you have any thoughts on how we should proceed with implementing this? Should I start by outlining the internal structure of the new module?

I'll take a look at your commits in just a sec, but what you outlined in the first sentence -- one module with multiple packages in it -- sounds good to me.

As for the name of the module maybe one of kobwebx-core-serialization, kobwebx-serialization-extensions.

I'm currently leaning towards kobwebx-core-serialization-kotlinx (as there are other serialization libraries out there besides the kotlinx one). But that is a mouthful, so I will think a bit more about it. Feel free to let me know if you think it is awful :)

Still, you don't need to feel blocked by a name. We can always check it in with one thing and we still have time to come up with another name before releasing 0.19.3.

(Not something to worry about in this commit, but I will also be considering if maybe we should merge the Kobweb worker serialization extension utilities into whatever we're creating here)

Copy link
Collaborator

@bitspittle bitspittle left a comment

Choose a reason for hiding this comment

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

Everything generally looks like it is in the right place, so this should be the only round of comments. I don't think anything should be too difficult to resolve!

playground/site/build.gradle.kts Outdated Show resolved Hide resolved
@@ -27,7 +27,7 @@ class ApiFetcher(private val window: Window) {
*/
var logOnError: Boolean by window.http::logOnError

private fun toResource(apiPath: String, autoPrefix: Boolean): String {
fun toResource(apiPath: String, autoPrefix: Boolean): String {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Instead of exposing this method, let's keep it private and use the following pattern in the extension code:

suspend inline fun <reified T> ApiFetcher.get(
    apiPath: String,
    headers: Map<String, Any>? = null,
    abortController: AbortController? = null,
    autoPrefix: Boolean = true,
    serializer: DeserializationStrategy<T> = serializer()
): T = Json.decodeFromString(serializer, window.api.get(apiPath, headers, abortController, autoPrefix).decodeToString())

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But window.api.get don't accept autoPrefix. I think we dont need Json.decodeFromString as we are calling the http methods from HttpFetcherSerializationExt.kt which will handle json decoding

We want to prepend api calls with /api so i made that method public. Maybe i can add a private method in ApiFetcherExtensions file for that ?

Copy link
Collaborator

Choose a reason for hiding this comment

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

The code snippet I included above is copied from my local copy of the code and it seems to be working fine? (autoPrefix is indeed an argument in ApiFetcher.get)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry!! I was reading that as window.http not window.api. making the change

frontend/kobwebx-core-serialization/build.gradle.kts Outdated Show resolved Hide resolved
settings.gradle.kts Outdated Show resolved Hide resolved
@bitspittle
Copy link
Collaborator

bitspittle commented Oct 14, 2024

BTW, LoP brought up a great question to me offline, and this is something I can do this in a followup commit (so not blocking your changes), but I thought I'd reach out to you first in case you had any thoughts about it.

Basically: should we treat body payloads as something that can also be serialized?

This would look like this:

suspend inline fun <reified B, reified R> ApiFetcher.post(
    apiPath: String,
    headers: Map<String, Any>? = null,
    body: B? = null,
    abortController: AbortController? = null,
    autoPrefix: Boolean = true,
    bodySerializer: SerializationStrategy<B> = serializer(),
    responseSerializer: DeserializationStrategy<R> = serializer()
): R = window.http.post(
    toResource(apiPath, autoPrefix),
    headers,
    body?.let { Json.encodeToString(bodySerializer, it).encodeToByteArray() },
    abortController,
    responseSerializer
)

Any thoughts?

@dead8309
Copy link
Contributor Author

dead8309 commented Oct 14, 2024

Definitely!!

@dead8309
Copy link
Contributor Author

dead8309 commented Oct 14, 2024

We only want to support body serialization for API routes, right? Or do you think I should also add support for HTTP requests as well?

@bitspittle
Copy link
Collaborator

We only want to support body serialization for API routes, right? Or do you think I should also add support for HTTP requests as well?

Ah yeah we should do both. The APIs are definitely related and should feel consistent.

Copy link
Collaborator

@bitspittle bitspittle left a comment

Choose a reason for hiding this comment

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

I'm going to go ahead and approve these changes. We'll merge after HttpFetcher also has its body APIs updated.

If you're busy and would like me to handle that in a followup commit, just let me know.

Thanks again for this PR!

@dead8309 dead8309 force-pushed the 602-add-kobwebx-browser-serialization branch from 81d3b19 to 522bf17 Compare October 14, 2024 21:53
…and ApiFetcher

- Closes varabyte#602
- Add HttpPage in playground for testing Serialization
- Sort the ordering of new module in settings.gradle
- Allow for serializing body payloads too
@dead8309 dead8309 force-pushed the 602-add-kobwebx-browser-serialization branch from 522bf17 to d0ec280 Compare October 14, 2024 22:03
@bitspittle bitspittle merged commit 7b5f9fa into varabyte:0.19.3 Oct 14, 2024
1 check passed
@bitspittle bitspittle added the hacktoberfest-accepted https://hacktoberfest.com/participation/ label Oct 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hacktoberfest-accepted https://hacktoberfest.com/participation/
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants