API를 사용하여 특정 주제의 모든 게시글 가져오기

:notebook_with_decorative_cover: 이는 Discourse API를 사용하여 특정 주제(Topic)의 모든 게시글(Post)을 가져오는 방법을 설명하는 안내서입니다.

Discourse API의 많은 라우트에서 반환되는 결과는 페이지네이션(페이지 나누기) 처리됩니다.

예를 들어, “단일 주제 가져오기” API 엔드포인트(예: https://examplesite/t/{id}.json)는 주제가 20개 이상의 게시글을 포함하더라도 기본적으로 20개의 게시글만 반환합니다.

이러한 동작으로 인해, .../t/{id}.json 엔드포인트를 사용하여 주제의 모든 게시글을 가져오는 두 가지 방법이 있습니다.

쿼리 파라미터 추가

주제의 모든 게시글을 가져오는 가장 쉬운 방법은 요청하는 URL에 print=true 쿼리 파라미터를 추가하는 것입니다.

예: https://examplesite/t/{id}.json?print=true

print=true 쿼리 파라미터가 추가되면 Discourse는 반환되는 게시글 수를 나타내는 chunk_size를 1000으로 설정합니다. 이는 주제가 1000개 이상의 게시글을 포함하지 않는다고 확신할 수 있는 경우에만 좋은 접근 방식입니다.

여러 API 요청

모든 게시글을 가져오는 또 다른 방법은 주제의 모든 게시글을 가져오기 위해 여러 번의 API 요청을 수행하는 것입니다:

  1. 먼저, .../t/{id}.json 엔드포인트에 초기 GET 요청을 수행합니다. 여기에는 posts 배열과 stream 배열을 포함하는 posts_stream 해시(hash)가 포함됩니다. posts 배열은 처음 20개의 게시글을 제공합니다.

  2. 이제 주제 내의 모든 게시글 ID를 제공하는 stream 배열을 순환해야 합니다. 스트림에서 처음 20개의 게시글 ID를 제거하십시오(그렇지 않으면 이유 없이 다시 다운로드하게 됩니다).

  3. 그런 다음 “주제에서 특정 게시글 가져오기” .../t/{id}/posts.json 엔드포인트에 추가 요청을 수행하고, post_ids[]를 추가하여 stream 배열의 모든 ID를 20개씩 묶어서 전달할 수 있습니다. 예: .../t/{id}/posts.json?post_ids[]=46&post_ids[]=47&post_ids[]=48&post_ids[]=49&post_ids[]=50&post_ids[]=51&post_ids[]=52&post_ids[]=53&post_ids[]=54&post_ids[]=55&post_ids[]=56&post_ids[]=57&post_ids[]=58&post_ids[]=59&post_ids[]=60&post_ids[]=61&post_ids[]=62&post_ids[]=63&post_ids[]=64&post_ids[]=65

속도 제한 (Rate Limits)

여러 API 호출을 수행하는 동안 Error: you have performed this action many times, please try again later 메시지가 발생하면 API 키 속도 제한에 도달했음을 의미합니다.

Discourse에는 1시간당 수행할 수 있는 print=true 요청 수에 대한 제한이 있으며, 이는 max prints per hour per user 사이트 설정으로 제어됩니다. 이 설정은 기본적으로 사용자에게 1시간당 5개의 주제만 인쇄(print)할 수 있도록 허용합니다. 이 값을 0으로 설정하면 인쇄 기능이 완전히 비활성화됩니다(print=true 요청은 403 오류를 반환합니다).

요청한 사용자가 관리자(admin)인 경우 속도 제한이 적용되지 않는다는 점에 유의하십시오. 즉, 요청의 Api-Username 매개변수에 관리자의 사용자 이름(예: system)을 사용하는 API 키를 사용하여 인쇄 속도 제한을 우회할 수 있습니다.

print=true를 포함하지 않는 API 요청에서 속도 제한 오류가 발생하는 경우, 속도 제한을 초과하지 않도록 API 스크립트에 타임아웃을 추가하는 것을 권장합니다. 또는 429(요청 초과) 오류 코드를侦聽하고(listen) 해당 응답을 받을 때 요청을 백오프(backoff)하도록 할 수 있습니다.

참고로, 아래에 나열된 기본 속도 제한은 표준 및 비즈니스 호스팅 플랜에 적용됩니다:

:grey_exclamation: 자체 호스팅(Self Hosted) 전용 - Discourse API 속도 제한을 조정하는 방법에 대한 자세한 내용은 Available settings for global rate limits and throttling 을 참조하십시오.

11개의 좋아요

Is the ?page query param supported? It works, but in a surprising way - ?page=1 only returns the first post in the topic, so to paginate with the parameter you need to start with https://example.com/t/slug/topicId.json, then skip to https://example.com/t/slug/topicId.json?page=2, then keep going until you eventually get a 404 response.

Hi Simon,

Using the ?page=1 parameter with the Get a single topic endpoint will return the first 20 posts from a topic, and each subsequent page number will return up to 20 posts.

When there are no most posts available (EX: the page is too high and not valid), you’ll get a 404 response.

If you don’t specify a page number, the code will set a page number of 1, so ?page=1 is the same as not appending an explicit page to the topic request.

If you wanted to use this method to fetch all posts from a topic, you should be able to do so, even though it is not mentioned within the Discourse API Docs.

3개의 좋아요

Thanks! Working on a matrix bot to fetch post!

I think this is wrong. Set to 0 will disable print at all. The latest description for this setting is Maximum number of /print page impressions (set to 0 to disable printing).