programing

WordPress Rest API Get All Posts

javamemo 2023. 10. 2. 10:49
반응형

WordPress Rest API Get All Posts

저는 게시물을 얻기 위해 다음을 사용하고 있습니다.

http://demo.wp-api.org/wp-json/wp/v2/posts

이것은 기본적으로 문서에 언급된 10개의 게시물을 제공합니다.

하지만 나는 페이지를 추적할 필요 없이 모든 게시물을 원합니다.

그게 가능한가요?

그렇지 않다면 자바스크립트 루프를 실행하여 모든 게시물을 얻을 수 있는 방법이 있습니까?

감사해요.

이것을 해결하는 한가지 방법은 RxJS입니다.

다음과 같은 Observable 작은 스트림을 구축합니다.

  • 모든 포스트 데이터 출력
  • 게시물 또는 페이지의 총 수를 사전에 알도록 강요하지 않음
  • 페이지화의 맥락에서 "우리가 어디에 있는지"를 추적하도록 강요하지 않습니다.

사용할 라이브러리:

  • Axios(Node와 Browser 환경에서 모두 작동하므로 HTTP GET를 단순화하기 위해)
  • RxJS v6 (현재 Alpha 릴리스이지만 여기 API는 RxJS 5에서 동일)

사용자 환경과 사용 사례는 다양할 것입니다. 이 예에서는 Node 환경에 있을 것입니다.

/**
 *      This will get all posts from a default WordPress REST API
 *      First we see how many pages there are
 *      Then we make subsequent XHR requests (via Axios)
 *      That paginate through every page of posts
 */

// Importing Axios for simple AJAX request
const axios = require('axios')

// Importing RxJS @ v6.0.0-alpha.3
const { Observable, from, range } = require('rxjs')
const { switchMap, concatMap } = require('rxjs/operators')

const endpoint = 'http://demo.wp-api.org/wp-json/wp/v2/posts'

/**
 *      This sets up the initial request and the Observable stream
 *      In the return from the endpoint, the Axios request headers will have x-wp-totalpages,
 *      which gives us... the total pages of posts ;)
 */
const posts$ = Rx.Observable.from(axios.get(endpoint))
    /**
     *     We now know the total number of pages,
     *     so we'll switch to a new Observable that is just a range of numbers
     *     We'll start with 1, and end with whatever the total number of pages is
     *     This gives us a stream of 1--n--n--n... (example: 1, 2, 3, 4...)
     */
    .switchMap((
        { headers }, // using ES6 function header destructuring and arrow functions here
    ) => Rx.Observable.range(1, Number(headers['x-wp-totalpages'])))
    /**
     *     We can now paginate through all posts, getting 10/page
     *     concatMap will fire off a request, waits until it completes, and then fire the next one
     *     In each subsequent firing, we ask for the next page of posts
     */
    .concatMap(page =>
        axios.get(endpoint, {
            params: {
                page,
            },
        }),
    )
    .subscribe(
        // data here is an Array of WordPress Posts, tacking .length shows us how many per page we are getting
        ({ data }) => console.log(data.length),
        err => console.log('Oh no, an error!', err),
    )

자원.

wp_remote_retrieve_body($url) 또는 wp_remote_post($url)를 사용하여 정지 API 사용 대신 게시물 데이터를 가져올 수 있습니다.wp_remote 함수는 기본 페이지화와 독립적입니다.

node.js에서 이 함수를 사용할 수 있습니다.

const getAllPosts = async (wordpressUrl) => {
  const url = `${wordpressUrl}/wp-json/wp/v2/posts?per_page=100`

  const maxPages = 50
  let page = 1
  let text
  const responses = []
  while (true) {
    const urlWithPage = `${url}&page=${page}`
    const res = await fetch(urlWithPage)
    text = await res.text()
    text = text.trim()
    if (res.status !== 200) {
      break
    }
    if (text === '[]') {
      break
    }
    if (!text.match(/^\[/) || !text.match(/\]$/)) {
      break
    }
    text = text.replace(/^\[/, '').replace(/\]$/, '')
    responses.push(text)

    if (page > maxPages) {
      break
    }
    page++
  }

  // get all pages and join them
  if (responses.length) {
    return `[${responses.join(',')}]`
  }

  // if didn't get any valid repsonses, send the text received
  return text
}

쿼리가 크면 사이트 성능이 저하될 수 있으므로per_page100개의 레코드로 제한되어 있습니다.예를 들어, 사용 가능한 모든 범주의 클라이언트 측 목록을 작성하는 등 100개 이상의 레코드를 검색하려는 경우, 여러 개의 API 요청을 하고 응용프로그램 내에서 결과를 결합할 수 있습니다.복잡한 설명은 이 페이지를 참조하십시오.

저는 타이프스크립트를 이용하여 리액트 네이티브로 앱을 작성하고 있지만, 워드프레스 GET 요청 결과를 통해 페이지를 작성하는 기본 원리는 비슷할 것입니다.

  1. 1로 초기화된 'page' 쿼리 매개변수를 사용하여 요청합니다(여기서는 0에서 시작하기 위해 템테이션과 싸웁니다).
  2. 수신할 "페이지" 또는 게시물 배치의 총 개수인 "x-wp-total pages"(응답 헤더를 통해 반환됨)를 받습니다.
  3. 현재 변수와 총 페이지 수를 비교하고 배열이 게시물로 모두 채워질 때까지 함수를 재귀적으로 호출합니다.

Wordpress REST API 페이지화 설명서를 읽는데 도움이 되었습니다.

async getPosts(current = 1, allPosts = []): Promise < Types.GetPostsResult > {
  // make the api call
  const response: ApiResponse < ApiFeedResponse > = await this.apisauce.get(
    Config.API_URL + '/posts', {
      per_page: 100,
      page: current
    })

  if (!response.ok) {
    const problem = getGeneralApiProblem(response)
    if (problem) return problem
  }

  const totalNumberOfPages = Number(response.headers['x-wp-totalpages']);

  try {
    const rawPosts = response.data
    // transform the data into the format we are expecting
    const convertedPosts: PostSnapshotOut[] = rawPosts.map(convertPost)

    allPosts.push(...convertedPosts);

    if (current < totalNumberOfPages) {
      this.getPosts(current + 1, allPosts);
    }

    return {
      kind: "ok",
      posts: allPosts
    }
  } catch (e) {
    console.error(e)
    if (__DEV__) {
      console.tron.error(`Bad data: ${e.message}\n${response.data}`, e.stack)
    }
    return {
      kind: "bad-data"
    }
  }
}

언급URL : https://stackoverflow.com/questions/48494711/wordpress-rest-api-get-all-posts

반응형