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

Re-architect Lemmy client (with support for v4) #30

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

hjiangsu
Copy link
Member

@hjiangsu hjiangsu commented Dec 21, 2024

Alright, this PR is going to be a bit on the larger side, so buckle up! I’m leaving it in draft status for now while I gather more feedback and work on making it a bit more feature-complete.

Note

This only works with v4 instances at the moment. As v4 instances are not generally available yet, you will have to
initialize a new Lemmy instance using the current main branch on Lemmy.

This re-architecture will first focus on v4 compatibility. Support for v3 will likely also come, but only after v4 is
more feature-complete.

Background

The initial goal of this PR was to add support for the v4 version of the Lemmy API, which is expected to be introduced in v0.20.0. The v4 version introduces significant changes to many of the existing endpoints to better align them with their respective domains and actions.

Given these changes, I thought it would be a good opportunity to rethink how we’re handling our current client. My goal with this re-architecture is to make our client easier and more intuitive to use, as well as being able to better handle breaking changes to the Lemmy API.

Major Changes

Here are the main goals of this re-architecture:

  • Abstraction: I wanted to add a bit more abstraction between our client, and the underlying Lemmy API. The abstraction layer will hopefully serve as a way to reduce the amount of changes required on the app side (e.g., Thunder) whenever there is a new API version.
  • Ease of use: I wanted to make our Lemmy client a bit easier to use. Right now, using our client is a bit cumbersome as we need to always use lemmy.run() and pass in the auth token for every single request. Doing this feels a bit counter-intuitive, and I believe there are better methods for handling this.
  • Testing: Currently, we don't have any testing framework in place for our API client. This is less than ideal because it makes it difficult to test our client against different API versions and changes. With this re-architecture, I hope to introduce a better testing framework and help reduce potential regressions.

That said, this is still a work in progress, and I’m definitely open to suggestions and feedback from everyone! This re-architecture is partially inspired by PRAW (a Reddit Python API).

Examples

To give an example of how the new experimental client works in practice, I'll run through a few types of scenarios.

Client initialization

To initialize the client, we simply have to specify a few parameters, the only one that is required is the instance as all other parameters will have a default value or be optional (e.g, auth)

// Initializes a new instance of the Lemmy client, and
final client = await LemmyClient.initialize(
  instance: 'lemmy.world',
  scheme: 'https',
  version: 'v4',
  auth: token,
);

When a new client is initialized, it will automatically fetch the relevant Site and Account information (when a valid auth token is passed in). Once the client is initialized, all future requests will use the provided auth token if applicable.

  • By fetching the site and account information automatically, we can more easily access the relevant information without having to perform multiple calls.
  • This eliminates the need to pass in auth for every single request

Fetching Feeds

To fetch posts for a given feed (e.g., all, local, subscribed, moderator), we can do the following:

/// Initialize the client with default parameters
final client = await LemmyClient.initialize(instance: 'lemmy.world');

/// Fetches posts for the `all` feed
final feed = await client.feed(listingType: ListingType.all).posts();

/// Fetches active posts for `local` feed
final result = await client.feed(listingType: ListingType.local).posts(sort: PostSortType.active);

Work Left

There is still a lot of work left for this re-architecture. However, I thought I'd create a draft PR for this in order to get some additional feedback on these overall changes.

If we do decide to migrate to this re-architecture, then it will be a while before it's completed as I have to add additional methods to perform actions (e.g., search, moderator actions, etc) and add compatibility with the v3 API. Additionally, we'll have to make changes to Thunder to make it compatible with this re-architecture!

Additional note: The API changes follow this commit from lemmy_js_client: c59d755070f437ca38fcfc2191fb0a5a6b037965

@micahmo
Copy link
Member

micahmo commented Dec 23, 2024

Just based on your comment (I haven't dug into the code yet), I like the whole idea of this re-architecture! Nice going!

@hjiangsu hjiangsu force-pushed the experimental/v4 branch 3 times, most recently from 4f92895 to 82b036d Compare December 27, 2024 00:03
…th lemmy_dart_client and lemmy_api_client at the same time
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants