Skip to content

Commit

Permalink
feat: replace getRandomPost() with getRandomPostId()
Browse files Browse the repository at this point in the history
Reddit designed `/random` using http redirects, which means that getting
a random post actually requires _two_ api requests. While this is not
the end of the world, it does go against one of the design goals of
snoots: minimizing the amount of behind the scenes network requests.
Specifically, in this case, there are legitimate reasons (mostly
ratelimit related) that a user would need to know that getting a random
post takes two requests. Making this changes makes that relationship
very explicit.

If you want the old single-function behavior back, you can always make a
utility function:

```ts
async function getRandomPost(client: Client, subreddit?: string) {
  const postId = await client.subreddits.getRandomPostId(subreddit);
  return await client.posts.fetch(postId);
}
```

or even subclass Client:

```ts
class CustomClient extends Client {
  async getRandomPost(subreddit?: string) {
    const id = await this.subreddits.getRandomPostId(subreddit);
    return await this.posts.fetch(id);
  }
}
```

BREAKING CHANGE: `getRandomPost()` replace with `getRandomPostId()`.
  • Loading branch information
thislooksfun committed Apr 10, 2022
1 parent 87c9640 commit 8f56359
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 21 deletions.
20 changes: 10 additions & 10 deletions dochome.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,40 +97,40 @@ the largest:

What does this mean in practice? Here are some examples:

1. Reading the title of a random post from r/funny:
1. Reading the title of the newest post from r/funny:

```ts
// snoowrap
const title = await client.getSubreddit("funny").getRandomSubmission().title;
const title = await client.getSubreddit("funny").getNew()[0].title;

// snoots (literal translation)
const sub = await client.subreddits.fetch("funny");
const post = await sub.getRandomPost();
const title = post.title;
const post = await sub.getNewPosts().first();
const title = post?.title;

// snoots (preferred method, 1 fewer api call)
const post = await client.subreddits.getRandomPost("funny");
const title = post.title;
const post = await client.subreddits.getNewPosts("funny").first();
const title = post?.title;
```

1. Listing the authors of the newest posts in r/funny:
1. Listing the authors of the currently hot posts in r/funny:

```ts
// snoowrap
const posts = await client.getSubreddit("funny").getNew().fetchAll();
const posts = await client.getSubreddit("funny").getHot().fetchAll();
for (const post of posts) {
console.log(post.author.name);
}

// snoots (literal translation)
const sub = await client.subreddits.fetch("funny");
const posts = sub.getNewPosts();
const posts = sub.getHotPosts();
for await (const post of posts) {
console.log(p.author);
}

// snoots (preferred method, 1 fewer api call)
const posts = client.subreddits.getNewPosts("funny");
const posts = client.subreddits.getHotPosts("funny");
for await (const post of posts) {
console.log(p.author);
}
Expand Down
11 changes: 4 additions & 7 deletions src/reddit/subreddit/controls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -673,17 +673,14 @@ export class SubredditControls extends BaseControls {
}

/**
* Get a random post.
*
* @note Due to the way Reddit has implemented this, it actually takes _2_ API
* requests, not 1.
* Get the ID of a random post.
*
* @param subreddit The name of the subreddit. If this is left off it will
* query the front page of Reddit.
*
* @returns A promise that resolves to a random post.
* @returns A promise that resolves to a random post ID.
*/
async getRandomPost(subreddit?: string): Promise<Post> {
async getRandomPostId(subreddit?: string): Promise<string> {
const base = subreddit ? `r/${subreddit}/` : "";

// Reddit implemented '/random' by redirecting (302) to a random post.
Expand All @@ -696,7 +693,7 @@ export class SubredditControls extends BaseControls {
const postUrl = postInfo.data.location;
const match = randomRedirectPattern.exec(postUrl);
if (!match) throw new Error(`Invalid redirect URI '${postUrl}'`);
return await this.client.posts.fetch(match[1]);
return match[1];
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/reddit/subreddit/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -735,12 +735,12 @@ export class Subreddit extends Content implements SubredditData {
}

/**
* Get a random post from this subreddit.
* Get the ID of a random post from this subreddit.
*
* @returns A promise that resolves to a random post.
* @returns A promise that resolves to a random post ID.
*/
async getRandomPost(): Promise<Post> {
return this.controls.getRandomPost(this.displayName);
async getRandomPostId(): Promise<string> {
return this.controls.getRandomPostId(this.displayName);
}

/**
Expand Down

0 comments on commit 8f56359

Please sign in to comment.