0

Hi I'm building up a WordPress rest API's custom endpoint on my project. I'm using the following code to get the single response from the website.

function get_single_post( $request ) {
    
    $response = array();
    $args = [
        'id' => $request['id'],
        'post_type' => 'payment',
    ];
    $post = get_posts($args);

    $metas = get_post_meta($request['id'],'');
    $post_id = $post->ID;

    $response[$post_id]['response'] = $post[0];
    $response[$post_id]['metas'] = $metas;

    return $response;
}

add_action('rest_api_init', function(){
    register_rest_route('booking/v1', 'posts',[
        'methods'=> 'GET',
        'callback' => 'booking_posts',
    ]);
    
    register_rest_route('booking/v1','/posts/(?P<id>\d+)',[
        'methods' => 'GET',
        // Register the callback for the endpoint.
        'callback' => 'get_single_post',
    ]);
});

I'm not getting the post with the posts/ in my response. Kindly advise what I'm doing wrong here?

Here's my response:

{
"": {
"response": {
"ID": 12042,
"post_author": "10",
"post_date": "2020-06-12 15:15:42",
"post_date_gmt": "2020-06-12 14:15:42",
"post_content": "",
"post_title": "xxxxxxxxxxxxxxx",
"post_excerpt": "",
"post_status": "publish",
"comment_status": "closed",
"ping_status": "closed",
"post_password": "",
"post_name": "xxxxxxxxxxx",
"to_ping": "",
"pinged": "",
"post_modified": "2020-06-12 15:15:42",
"post_modified_gmt": "2020-06-12 14:15:42",
"post_content_filtered": "",
"post_parent": 0,
"guid": "https://xxxxxxxx/payment/xxxxxxxxxx/",
"menu_order": 0,
"post_type": "payment",
"post_mime_type": "",
"comment_count": "0",
"filter": "raw"
},
"metas": {
"chauffeur_payment_status": [
"Unpaid"
],
"chauffeur_payment_num_passengers": [
"1"
],
"chauffeur_payment_num_bags": [
"0"
],
"chauffeur_payment_first_name": [
"xxxxxxx"
],
"chauffeur_payment_last_name": [
"xxxxxxxx"
],
"chauffeur_payment_email": [
"xxxxxxxxx"
],
"chauffeur_payment_phone_num": [
"xxxxxx"
],
"chauffeur_payment_flight_number": [
""
],
"chauffeur_payment_additional_info": [
""
],
"chauffeur_payment_pickup_address": [
"xxxxxxx"
],
"chauffeur_payment_dropoff_address": [
"xxxxxxxx"
],
"chauffeur_payment_pickup_date": [
"12/06/2020"
],
"chauffeur_payment_pickup_time": [
"12:00"
],
"chauffeur_payment_trip_distance": [
"3,907 km"
],
"chauffeur_payment_trip_time": [
"1 day 12 hours"
],
"chauffeur_payment_item_name": [
"Standard-size taxi"
],
"chauffeur_payment_trip_type": [
"one_way"
],
"chauffeur_payment_return_journey": [
"One Way"
],
"chauffeur_payment_num_hours": [
""
],
"chauffeur_payment_amount": [
"xxxx"
],
"chauffeur_payment_full_pickup_address": [
""
],
"chauffeur_payment_pickup_instructions": [
""
],
"chauffeur_payment_full_dropoff_address": [
""
],
"chauffeur_payment_dropoff_instructions": [
""
]
}
}
}

The id of response->ID should be same as posts/. It's not.

1
  • instead of building a custom endpoint for a post type, have you considered setting show_in_rest when registering the post type instead and letting WP Core build an endpoint for you?
    – Tom J Nowell
    Jun 13 '20 at 14:06
1

You're getting that mismatched values because you're using the wrong argument for the post ID in your $args array (i.e. the query args for WP_Query). And the correct argument is p (lowercase P) and not id:

$args = [
//  'id' => $request['id'], // wrong argument name - 'id'
    'p' => $request['id'],  // and the correct one is 'p'
    'post_type' => 'payment',
];

And in addition to that main issue, another one I noticed is the $post_id = $post->ID; whereby that $post is an array and not object. So did you mean to use $post_id = $post[0]->ID; ?

Also, why do you have to use get_posts()? Why not just use get_post()$post = get_post( $request['id'] ); ? That way, the above $post_id = $post->ID; would be valid. So for example, this is how your code would look like when using get_post():

if ( ! $post = get_post( $request['id'] ) ) {
    return new WP_Error( 'your_error_code_here', 'Please define a valid post ID.' );
}

$metas = get_post_meta( $request['id'] );
$post_id = $post->ID;

$response[ $post_id ]['response'] = $post;
5
  • i didn't get your last line " And actually, the id argument is not valid for WP query. It should be p. " can you help me understand it? Jun 13 '20 at 12:46
  • and also upon using the get_post($request['id']); I'm getting a null response in my response object. Jun 13 '20 at 12:47
  • 1
    Thanks sally. Worked like a charm. Jun 13 '20 at 12:50
  • 1
    Sorry about the initial answer, but I'm glad the revised one helped. :)
    – Sally CJ
    Jun 13 '20 at 13:06
  • PS: For some post meta data, the value may not be appropriate to be made public unless maybe if you add some kind of restrictions, e.g. using the permission_callback argument when registering your custom endpoint, so you should include only the data your project needs and apply restrictions where necessary. :)
    – Sally CJ
    Jun 13 '20 at 14:59
0

Hope this helps someone, this uses ACF Custom Fields as well:

routes/site-route.php

<?php

class SiteRestRouter
{

  public function __construct()
  {
    $this->register_routes();
  }

  public function get_site($request)
  {
    $args = array(
      'p' => $request['id'],
      'post_type' => 'site',
    );

    if ( ! $post = get_post( $request['id'] ) ) {
      return new WP_Error( 'invalid_id', 'Please define a valid post ID.' );
    }

    $query = new WP_Query($args);

    if ($query -> have_posts()) {
      $query->the_post();
      $post = get_post(get_the_ID());
      $id = get_the_ID();
      $title = $post->post_title;
      $last_updated = get_field('last_updated');
      $deployment_location = get_field('location');
      $git_location = get_field('git_location');
      $database_location = get_field('database_location');
      $host = get_field('host');
      $protected_by_cloudflare = get_field('cloudflare');
      $maintenance = get_field('maintenance');
      $php_version = get_field('php_version');
      $wordpress_version = get_field('wordpress_version');
      $assigned_to = get_field('assigned_to');
      $notes = get_field('notes');
      $logs = get_field('logs');

      $response['id'] = $id;
      $response['title'] = $title;
      $response['last_updated'] = $last_updated;
      $response['deployment_location'] = $deployment_location;
      $response['git_location'] = $git_location;
      $response['database_location'] = $database_location;
      $response['host'] = $host;
      $response['protected_by_cloudflare'] = $protected_by_cloudflare;
      $response['maintenance'] = $maintenance;
      $response['php_version'] = $php_version;
      $response['wordpress_version'] = $wordpress_version;
      $response['assigned_to'] = $assigned_to->post_title;
      $response['notes'] = $notes;
      $response['logs'] = $logs;
    }

    wp_reset_postdata();

    return $response;
  }

  protected function register_routes()
    {
      add_action('rest_api_init', function () {
        $namespace = 'api/v1/';

        register_rest_route($namespace, '/sites/(?P<id>\d+)', array(
          'methods' => 'GET',
          'callback' => array( $this, 'get_site' ),
        ));
      });
    }
}

new SiteRestRouter();

Add this to functions.php

require_once 'routes/site-route.php';

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.