একটি RESTful URL তৈরির জন্য পুনর্লিখনের এপিআই ব্যবহার করে


19

আমি একটি RESTful API এর জন্য পুনর্লিখনের নিয়ম উত্পন্ন করার চেষ্টা করছি। আমি কেবল দেখতে চাই প্রতিটি সম্ভাব্য পুনর্লিখনের সংমিশ্রণটি লেখার চেয়ে এই কাজটি করার আরও ভাল উপায় আছে কিনা।

ঠিক আছে সুতরাং আমি ইউআরএল অ্যাকাউন্টে 4 টি ক্যোয়ারী ভেরিয়েবল আছে

  • ইনডিকেটর
  • দেশ
  • প্রতিক্রিয়া
  • জরিপ

বেস url হবে www.example.com/some-page/ 4 টি ভেরিয়েবলের ক্রম সামঞ্জস্যপূর্ণ তবে কিছু ক্যোয়ারী ভেরিয়েবলগুলি alচ্ছিক।

সুতরাং আমি থাকতে পারে ...

/indicator/{indicator value}/country/{country value}/response/{response value}/survey/{survey value}/

বা ... (না / প্রতিক্রিয়া /)

/indicator/{indicator value}/country/{country value}/survey/{survey value}/

বা ...

/indicator/{indicator value}/country/{country value}/

এটি সম্পাদন করার জন্য rewrite_rules_arrayম্যানুয়ালি তৈরি হওয়া আমার পুনর্লিখনের নিয়মের একটি অ্যারে যুক্ত করার চেয়ে কি আরও ভাল উপায় আছে ? চান add_rewrite_endpoint()rewrite_endpoint বা add_rewrite_tag()আমাকে কোন ব্যবহার করা হবে?

উত্তর:


18

আমি মনে করি সেরা বিকল্পটি একটি শেষ পয়েন্ট। আপনি একটি সাধারণ স্ট্রিং হিসাবে সমস্ত ডেটা পান, সুতরাং এটি কীভাবে পার্স করা হবে তা আপনি সিদ্ধান্ত নিতে পারেন এবং অন্যান্য পুনর্লিখনের নিয়মের সাথে সংঘর্ষের বিষয়ে আপনাকে চিন্তা করতে হবে না।

আমি শেষ পয়েন্টগুলি সম্পর্কে একটি জিনিস শিখেছি: মূল কাজটি যতটা সম্ভব বিমূর্তভাবে রাখুন, ডেটা অজ্ঞায়নের উপায়ে ওয়ার্ডপ্রেস 'এপিআইয়ের গ্লিটগুলি ঠিক করুন।

আমি যুক্তিটিকে তিনটি ভাগে বিভক্ত করব: একটি নিয়ামক একটি মডেল এবং একটি ভিউ নির্বাচন করেন, শেষ পয়েন্টটি পরিচালনা করতে একটি মডেল এবং কিছু দরকারী ডেটা বা ত্রুটি বার্তাগুলি ফেরত দেওয়ার জন্য এক বা একাধিক মতামত নির্বাচন করেন।

নিয়ামক

কন্ট্রোলার দিয়ে শুরু করা যাক। এটি বেশি কিছু করে না, তাই আমি এখানে খুব সাধারণ ফাংশন ব্যবহার করি:

add_action( 'plugins_loaded', 't5_cra_init' );

function t5_cra_init()
{
    require dirname( __FILE__ ) . '/class.T5_CRA_Model.php';

    $options = array (
        'callback' => array ( 'T5_CRA_View_Demo', '__construct' ),
        'name'     => 'api',
        'position' => EP_ROOT
    );
    new T5_CRA_Model( $options );
}

মূলত, এটি মডেলটি লোড করে T5_CRA_Modelএবং কিছু পরামিতিগুলি হস্তান্তর করে ... এবং সমস্ত কাজ। নিয়ামকটি মডেলের অভ্যন্তরীণ যুক্তি বা ভিউ সম্পর্কে কিছুই জানেন না। এটি উভয় একসাথে লাঠি। এটি কেবলমাত্র এমন অংশ যা আপনি পুনরায় ব্যবহার করতে পারবেন না; এ কারণেই আমি এটিকে অন্যান্য অংশ থেকে আলাদা করে রেখেছি।


এখন আমাদের কমপক্ষে দুটি ক্লাস দরকার: মডেল যা এপিআই এবং আউটপুট তৈরির জন্য ভিউ নিবন্ধন করে ।

মডেলটি

এই শ্রেণি করবে:

  • শেষ পয়েন্ট নিবন্ধন করুন
  • কোনও অতিরিক্ত পরামিতি ছাড়াই সেখানে শেষ বিন্দুতে কল করা মামলাগুলি ধরুন
  • পুনর্লিখনের নিয়মগুলি পূরণ করুন যা তৃতীয় পক্ষের কোডে কিছু বাগের কারণে অনুপস্থিত
  • স্থির সম্মুখ পৃষ্ঠাগুলি এবং এর জন্য শেষ পয়েন্ট সহ একটি ওয়ার্ডপ্রেস ভুল EP_ROOT
  • ইউআরআইকে একটি অ্যারেতে পার্স করুন (এটিও আলাদা করা যেতে পারে)
  • সেই মানগুলির সাথে কলব্যাক হ্যান্ডলারকে কল করুন

আমি আশা করি কোডটি নিজের পক্ষে কথা বলবে। :)

মডেলটি ডেটার অভ্যন্তরীণ কাঠামো বা উপস্থাপনা সম্পর্কে কিছুই জানে না। সুতরাং আপনি এটি এক লাইন পরিবর্তন না করে শত শত এপিআই নিবন্ধন করতে ব্যবহার করতে পারেন।

<?php  # -*- coding: utf-8 -*-
/**
 * Register new REST API as endpoint.
 *
 * @author toscho http://toscho.de
 *
 */
class T5_CRA_Model
{
    protected $options;

    /**
     * Read options and register endpoint actions and filters.
     *
     * @wp-hook plugins_loaded
     * @param   array $options
     */
    public function __construct( Array $options )
    {
        $default_options = array (
            'callback' => array ( 'T5_CRA_View_Demo', '__construct' ),
            'name'     => 'api',
            'position' => EP_ROOT
        );

        $this->options = wp_parse_args( $options, $default_options );

        add_action( 'init', array ( $this, 'register_api' ), 1000 );

        // endpoints work on the front end only
        if ( is_admin() )
            return;

        add_filter( 'request', array ( $this, 'set_query_var' ) );
        // Hook in late to allow other plugins to operate earlier.
        add_action( 'template_redirect', array ( $this, 'render' ), 100 );
    }

    /**
     * Add endpoint and deal with other code flushing our rules away.
     *
     * @wp-hook init
     * @return void
     */
    public function register_api()
    {
        add_rewrite_endpoint(
            $this->options['name'],
            $this->options['position']
        );
        $this->fix_failed_registration(
            $this->options['name'],
            $this->options['position']
        );
    }

    /**
     * Fix rules flushed by other peoples code.
     *
     * @wp-hook init
     * @param string $name
     * @param int    $position
     */
    protected function fix_failed_registration( $name, $position )
    {
        global $wp_rewrite;

        if ( empty ( $wp_rewrite->endpoints ) )
            return flush_rewrite_rules( FALSE );

        foreach ( $wp_rewrite->endpoints as $endpoint )
            if ( $endpoint[0] === $position && $endpoint[1] === $name )
                return;

        flush_rewrite_rules( FALSE );
    }

    /**
     * Set the endpoint variable to TRUE.
     *
     * If the endpoint was called without further parameters it does not
     * evaluate to TRUE otherwise.
     *
     * @wp-hook request
     * @param   array $vars
     * @return  array
     */
    public function set_query_var( Array $vars )
    {
        if ( ! empty ( $vars[ $this->options['name'] ] ) )
            return $vars;

        // When a static page was set as front page, the WordPress endpoint API
        // does some strange things. Let's fix that.
        if ( isset ( $vars[ $this->options['name'] ] )
            or ( isset ( $vars['pagename'] ) and $this->options['name'] === $vars['pagename'] )
            or ( isset ( $vars['page'] ) and $this->options['name'] === $vars['name'] )
            )
        {
            // In some cases WP misinterprets the request as a page request and
            // returns a 404.
            $vars['page'] = $vars['pagename'] = $vars['name'] = FALSE;
            $vars[ $this->options['name'] ] = TRUE;
        }
        return $vars;
    }

    /**
     * Prepare API requests and hand them over to the callback.
     *
     * @wp-hook template_redirect
     * @return  void
     */
    public function render()
    {
        $api = get_query_var( $this->options['name'] );
        $api = trim( $api, '/' );

        if ( '' === $api )
            return;

        $parts  = explode( '/', $api );
        $type   = array_shift( $parts );
        $values = $this->get_api_values( join( '/', $parts ) );
        $callback = $this->options['callback'];

        if ( is_string( $callback ) )
        {
            call_user_func( $callback, $type, $values );
        }
        elseif ( is_array( $callback ) )
        {
            if ( '__construct' === $callback[1] )
                new $callback[0]( $type, $values );
            elseif ( is_callable( $callback ) )
                call_user_func( $callback, $type, $values );
        }
        else
        {
            trigger_error(
                'Cannot call your callback: ' . var_export( $callback, TRUE ),
                E_USER_ERROR
            );
        }

        // Important. WordPress will render the main page if we leave this out.
        exit;
    }

    /**
     * Parse request URI into associative array.
     *
     * @wp-hook template_redirect
     * @param   string $request
     * @return  array
     */
    protected function get_api_values( $request )
    {
        $keys    = $values = array();
        $count   = 0;
        $request = trim( $request, '/' );
        $tok     = strtok( $request, '/' );

        while ( $tok !== FALSE )
        {
            0 === $count++ % 2 ? $keys[] = $tok : $values[] = $tok;
            $tok = strtok( '/' );
        }

        // fix odd requests
        if ( count( $keys ) !== count( $values ) )
            $values[] = '';

        return array_combine( $keys, $values );
    }
}

দৃশ্য

এখন আমাদের আমাদের ডেটা দিয়ে কিছু করতে হবে। আমরা অসম্পূর্ণ অনুরোধগুলির জন্য অনুপস্থিত ডেটা ধরতে পারি বা হ্যান্ডলিংটিকে অন্য ভিউ বা সাব-কন্ট্রোলারদের ডেলিগেট করতে পারি।

এখানে একটি খুব সাধারণ উদাহরণ:

class T5_CRA_View_Demo
{
    protected $allowed_types = array (
            'plain',
            'html',
            'xml'
    );

    protected $default_values = array (
        'country' => 'Norway',
        'date'    => 1700,
        'max'     => 200
    );
    public function __construct( $type, $data )
    {
        if ( ! in_array( $type, $this->allowed_types ) )
            die( 'Your request is invalid. Please read our fantastic manual.' );

        $data = wp_parse_args( $data, $this->default_values );

        header( "Content-Type: text/$type;charset=utf-8" );
        $method = "render_$type";
        $this->$method( $data );
    }

    protected function render_plain( $data )
    {
        foreach ( $data as $key => $value )
            print "$key: $value\n";
    }
    protected function render_html( $data ) {}
    protected function render_xml( $data ) {}
}

গুরুত্বপূর্ণ অংশটি হল: ভিউটি শেষ পয়েন্ট সম্পর্কে কিছুই জানে না। আপনি একে সম্পূর্ণ ভিন্ন অনুরোধগুলি পরিচালনা করতে ব্যবহার করতে পারেন, উদাহরণস্বরূপ এজেএক্স অনুরোধগুলি wp-admin। আপনি ভিউটিকে তার নিজস্ব এমভিসি প্যাটার্নে ভাগ করতে পারেন বা কেবল একটি সাধারণ ফাংশন ব্যবহার করতে পারেন।


2
অঙ্ক. আমি এই ধরণের প্যাটার্ন পছন্দ করি।
কিংকুল68
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.