রেল রুটগুলির জন্য API সংস্করণ


141

আমি স্ট্রাইপের মতো আমার এপিআই সংস্করণ করার চেষ্টা করছি। নীচে সর্বশেষতম এপিআই সংস্করণটি দেওয়া হল 2।

/api/users 301 এ ফেরত দেয় /api/v2/users

/api/v1/users সংস্করণ 1 এ ব্যবহারকারীদের সূচকের 200 টি প্রদান করে

/api/v3/users 301 এ ফেরত দেয় /api/v2/users

/api/asdf/users 301 এ ফেরত দেয় /api/v2/users

সুতরাং মূলত যে কোনও কিছুই যা সংস্করণটিকে নির্দিষ্ট করে না তবে নির্দিষ্ট সংস্করণটি উপস্থিত না থাকলে তার সাথে পুনঃনির্দেশ করা উচিত।

আমার এ পর্যন্ত যা আছে:

scope 'api', :format => :json do
  scope 'v:api_version', :api_version => /[12]/ do
    resources :users
  end

  match '/*path', :to => redirect { |params| "/api/v2/#{params[:path]}" }
end

উত্তর:


280

এই উত্তরের মূল ফর্মটি বন্যভাবে আলাদা এবং এটি এখানে পাওয়া যাবে । একটি বিড়ালকে চামড়ার একাধিক উপায় ছাড়াও প্রমাণ।

আমি নেমস্পেসগুলি ব্যবহার করতে এবং 302 এর পূর্বনির্ধারিত পরিবর্তে 301 পুনঃনির্দেশগুলি ব্যবহার করার জন্য উত্তরটি আপডেট করেছি those পিকসেল্ট্রিক্স এবং বো জিনেসকে ধন্যবাদ এই বিষয়গুলির জন্য অনুরোধ করার জন্য।


আপনি একটি পরতে চাইবেন সত্যিই শক্তিশালী শিরস্ত্রাণ কারণ এই যাচ্ছে আপনার মন গাট্টা

রেল 3 রাউটিং এপিআই সুপার দুষ্ট। আপনার এপিআই-র জন্য রুটগুলি লিখতে, উপরে আপনার প্রয়োজনীয়তা অনুসারে, আপনার কেবল এটির প্রয়োজন:

namespace :api do
  namespace :v1 do
    resources :users
  end

  namespace :v2 do
    resources :users
  end
  match 'v:api/*path', :to => redirect("/api/v2/%{path}")
  match '*path', :to => redirect("/api/v2/%{path}")
end

এই বিষয়টির পরে যদি আপনার মন এখনও অক্ষত থাকে তবে আমাকে ব্যাখ্যা করুন।

প্রথমে আমরা কল করি namespaceযা আপনি যখন নির্দিষ্ট নাম এবং নির্দিষ্ট মডিউলের অনুরূপ নামকরণ করা পথের একটি গোছা চান তখন এর জন্য খুব কার্যকর। এক্ষেত্রে আমরা চাইব যে আমাদের ব্লকের ভিতরে থাকা সমস্ত namespaceরুটগুলিকে Apiমডিউলটির মধ্যে থাকা নিয়ন্ত্রকদের কাছে স্কোপ করা হবে এবং এই রুটের অভ্যন্তরের পাথগুলিতে সমস্ত অনুরোধগুলি উপসর্গযুক্ত করা হবে api। অনুরোধ যেমন /api/v2/users, ইয়া জানেন?

নেমস্পেসের অভ্যন্তরে, আমরা আরও দুটি নাম স্থান (ওহো!) সংজ্ঞায়িত করি। এই সময় আমরা "v1 এ" নামস্থান সংজ্ঞা করছি, তাই কন্ট্রোলার এখানে সব রুটে ভিতরে হতে হবে V1ভিতরে মডিউল Apiমডিউল: Api::V1resources :usersএই রুটের ভিতরে সংজ্ঞা দিয়ে, নিয়ামকটি এখানে অবস্থিত হবে Api::V1::UsersController। এটি সংস্করণ ১, এবং আপনি অনুরোধ করে সেখানে পৌঁছে যান /api/v1/users

সংস্করণ 2 শুধুমাত্র একটি হল অতি ক্ষুদ্র একটু ভিন্ন। নিয়ন্ত্রকটি এটিতে উপস্থিত হওয়ার পরিবর্তে Api::V1::UsersControllerএটি এখন Api::V2::UsersController। আপনি অনুরোধ করে সেখানে পাবেন /api/v2/users

এর পরে, একটি matchব্যবহার করা হয়। এটি এমন সমস্ত API রুটের সাথে মিলবে যা এই জাতীয় জিনিসগুলিতে যায় /api/v3/users

এই অংশটি আমার সন্ধান করতে হবে। :to =>বিকল্প আপনাকে তা নির্দিষ্ট করার যে একটি নির্দিষ্ট অনুরোধ অন্য কোথাও আপনাকে পুনঃনির্দেশিত করা উচিত দেয় - আমি জানতাম যে কত - কিন্তু আমি কিভাবে এটা অন্য কোথাও পুনর্চালনা এবং এটি সঙ্গে বরাবর আসল অনুরোধটি এক টুকরা মধ্যে পাস পেতে জানেন না ।

এটি করার জন্য, আমরা redirectপদ্ধতিটি কল করি এবং এটি একটি বিশেষ-ইন্টারপোল্টেড %{path}প্যারামিটার সহ একটি স্ট্রিং পাস করি । যখন এই অনুরোধটি এই চূড়ান্ত সাথে মেলে তখন matchএটি pathপ্যারামিটারটিকে %{path}স্ট্রিংয়ের ভিতরে অবস্থিত করে এবং ব্যবহারকারীকে তাদের যেখানে যেতে হবে সেখানে পুনর্নির্দেশ করবে।

অবশেষে, আমরা matchপূর্বনির্ধারিত বাকী সমস্ত পাথগুলি রুট করতে /apiএবং এগুলিতে পুনঃনির্দেশ করার জন্য অন্যটি ব্যবহার করি /api/v2/%{path}। এর অর্থ হল অনুরোধগুলি যেমন /api/usersযাবে /api/v2/users

আমি জিনিসটা করতে পারেনি কিভাবে পেতে /api/asdf/usersমেলে, কারণ আপনি কিভাবে নির্ধারণ যে যদি একটি অনুরোধ হতে অনুমিত হয় /api/<resource>/<identifier>বা /api/<version>/<resource>?

যাইহোক, এটি গবেষণা মজাদার ছিল এবং আমি আশা করি এটি আপনাকে সহায়তা করবে!


24
প্রিয় রায়ান বিগ আপনি মেধাবী.
জেনারেল

18
কেউ কেবল রুবি হিরোর খ্যাতি পরিমাপ করে না।
ওয়াসিম

1
রায়ান ... আমি মনে করি এটি আসলে সঠিক নয়। এটিতে / এপিআই এবং / এপিআই / ভি 2 একক ক্যানোনিকাল URL না রেখে একই বিষয়বস্তু পরিবেশন করবে। / এপিআই / এপিআই / ভি 2 এ পুনঃনির্দেশ করা উচিত (মূল লেখক নির্দিষ্ট হিসাবে)। আমি আশা করি সঠিক রুটগুলি gist.github.com/2044335 এর মতো দেখতে হবে (মঞ্জুর হয়েছে, যদিও আমি এটি পরীক্ষা করি নি)। কেবল / এপিআই / ভি [12] 200, / এপিআই এবং / এপিআই / <খারাপ সংস্করণ> 301 এস / এপিআই / ভি 2 তে ফিরে আসতে হবে
বো জিনেস

2
এটি লক্ষণীয় যে রুটে 301 ফাইলটিকে ডিফল্ট পুনর্নির্দেশ করা হয়েছে এবং ভাল কারণে তৈরি করা হয়েছে। গাইডগুলি থেকে: Please note that this redirection is a 301 “Moved Permanently” redirect. Keep in mind that some web browsers or proxy servers will cache this type of redirect, making the old page inaccessible.
জালিয়াতি করুন

3
পথটি সঠিক না হলে এটি কি অসীম পুনর্নির্দেশগুলি তৈরি করে না? উদাহরণস্বরূপ, / এপিআই / ভি 3 / পাথ_টাকে_ডন্ট_ম্যাচ_এই_উউর্টগুলি অনুরোধ করা একটি অসীম পুনঃনির্দেশ তৈরি করবে, তাই না?
রবিন

38

যুক্ত করার জন্য কয়েকটি জিনিস:

আপনার পুনর্নির্দেশ ম্যাচটি কয়েকটি নির্দিষ্ট রুটের জন্য কাজ করছে না - পরম *apiলোভী এবং সমস্ত কিছু গ্রাস /api/asdf/users/1করবে , উদাহরণস্বরূপ পুনঃনির্দেশ করবে /api/v2/1। আপনি নিয়মিত প্যারামের মতো ব্যবহার করা ভাল :api। স্বীকার করা যায় এটি এর মতো মামলার সাথে মেলে না /api/asdf/asdf/users/1তবে আপনি যদি আপনার এপিআই-তে সংস্থান তৈরি করে থাকেন তবে এটি আরও ভাল সমাধান।

রায়ান কেন আপনার পছন্দ নেই namespace? :-), যেমন:

current_api_routes = lambda do
  resources :users
end

namespace :api do
  scope :module => :v2, &current_api_routes
  namespace :v2, &current_api_routes
  namespace :v1, &current_api_routes
  match ":api/*path", :to => redirect("/api/v2/%{path}")
end

যার সংস্করণযুক্ত এবং জেনেরিক নামক রুটের যুক্ত সুবিধা রয়েছে। একটি অতিরিক্ত নোট - ব্যবহারের সময় কনভেনশন :moduleহ'ল আন্ডারস্কোর নোটেশন ব্যবহার করা, যেমন: api/v1'অপি :: ভি 1' নয়। এক পর্যায়ে দ্বিতীয়টি কাজ করেনি তবে আমি বিশ্বাস করি এটি রেল ৩.১ এ স্থির ছিল।

এছাড়াও, আপনি যখন আপনার API এর v3 প্রকাশ করবেন তখন রুটগুলি এভাবে আপডেট করা হবে:

current_api_routes = lambda do
  resources :users
end

namespace :api do
  scope :module => :v3, &current_api_routes
  namespace :v3, &current_api_routes
  namespace :v2, &current_api_routes
  namespace :v1, &current_api_routes
  match ":api/*path", :to => redirect("/api/v3/%{path}")
end

অবশ্যই এটি সম্ভবত আপনার API এর সংস্করণের মধ্যে বিভিন্ন রুট রয়েছে যার ক্ষেত্রে আপনি এটি করতে পারেন:

current_api_routes = lambda do
  # Define latest API
end

namespace :api do
  scope :module => :v3, &current_api_routes
  namespace :v3, &current_api_routes

  namespace :v2 do
    # Define API v2 routes
  end

  namespace :v1 do
    # Define API v1 routes
  end

  match ":api/*path", :to => redirect("/api/v3/%{path}")
end

আপনি কিভাবে চূড়ান্ত মামলা মোকাবেলা করবে? অর্থাৎ /api/asdf/users?পাশাপাশি /api/users/1? আমার আপডেট হওয়া উত্তরে আমি এটি অনুধাবন করতে পারিনি, তাই অনুভূত হয়েছিল যে আপনি কোনও উপায় সম্পর্কে জানতে পারেন
রায়ান বিগ

এটি করার সহজ কোনও উপায় নেই - সমস্ত ক্যাপচারের আগে আপনাকে সমস্ত পুনঃনির্দেশগুলি সংজ্ঞায়িত করতে হবে তবে প্রতিটি প্যারেন্ট রিসোর্সগুলির জন্য আপনাকে কেবল প্রতিটি কাজ করতে হবে, যেমন / এপিআই / ব্যবহারকারী / * পাথ => / এপিআই / ভি 2 / ব্যবহারকারী /% {পাথ}
পিক্সেল্ট্রিক্স

13

যদি কিছুটা সম্ভব হয় তবে আমি আপনার ইউআরএলগুলি পুনর্বিবেচনা করার পরামর্শ দিচ্ছি যাতে সংস্করণটি ইউআরএলে না থাকে তবে গ্রহণযোগ্য শিরোনামে রেখে দেওয়া হয়। এই স্ট্যাকের ওভারফ্লো উত্তরটি এতে ভালভাবে যায়:

এপিআই সংস্করণ জন্য সেরা অনুশীলন?

এবং এই লিঙ্কটি রেল রুটিংয়ের মাধ্যমে ঠিক কীভাবে তা করবে তা দেখায়:

http://freelancing-gods.com/posts/versioning_your_ap_is


এটি এটি করার একটি দুর্দান্ত উপায় এবং সম্ভবত "/ এপিআই / এসিডেফ / ব্যবহারকারীদের" অনুরোধটিও পূরণ করতে পারে।
রায়ান বিগ

9

আমি রুটগুলি অনুসারে সংস্করণ করার বড় ভক্ত নই। আমরা এপিআই সংস্করণকরণের সহজ ফর্মটিকে সমর্থন করতে ভার্সনকেকটি তৈরি করেছি ।

আমাদের প্রতিটি নিজ নিজ মতামতের (জবিল্ডার, র‌্যাবএল, ইত্যাদি) ফাইলের নামের এপিআই সংস্করণ নম্বর অন্তর্ভুক্ত করে আমরা সংস্করণটিকে নিরর্থক রাখি এবং পিছনে সামঞ্জস্যতা সমর্থন করার জন্য সহজ অবক্ষয়ের জন্য অনুমতি দেয় (উদাহরণস্বরূপ যদি ভিউয়ের ভি 5 উপস্থিত না থাকে, আমরা ভিউ রেন্ডার করুন)।


8

আমি নিশ্চিত নই যে আপনি যদি কোনও সংস্করণ স্পষ্টভাবে অনুরোধ না করেন তবে আপনি কেন একটি নির্দিষ্ট সংস্করণে পুনর্নির্দেশ করতে চান । দেখে মনে হচ্ছে আপনি কেবল একটি ডিফল্ট সংস্করণ সংজ্ঞায়িত করতে চান যা কোনও সংস্করণ স্পষ্টভাবে অনুরোধ না করা থাকলে পরিবেশন করা হবে। আমি ডেভিড বকের সাথেও একমত যে ইউআরএল কাঠামোর বাইরে সংস্করণগুলি রাখা ভার্সনকে সমর্থন করার একটি ক্লিনার উপায়।

নির্লজ্জ প্লাগ: সংস্করণবিদ এই ব্যবহারের ক্ষেত্রে (এবং আরও অনেক কিছু) সমর্থন করে।

https://github.com/bploetz/versionist


2

রায়ান বিগ উত্তর আমার পক্ষে কাজ করেছে।

আপনি যদি পুনঃনির্দেশের মাধ্যমে ক্যোয়ারী প্যারামিটারগুলি রাখতে চান তবে আপনি এটি এটি করতে পারেন:

match "*path", to: redirect{ |params, request| "/api/v2/#{params[:path]}?#{request.query_string}" }

2

এটি আজই প্রয়োগ করা হয়েছে এবং রেলকাস্টে 'সঠিক পথ' বলে আমি বিশ্বাস করি - REST এপিআই সংস্করণ । খুবই সোজা. তাই রক্ষণাবেক্ষণযোগ্য। তাই কার্যকর।

যোগ করুন lib/api_constraints.rb(এমনকি vnd.example পরিবর্তন করতে হবে না।)

class ApiConstraints
  def initialize(options)
    @version = options[:version]
    @default = options[:default]
  end

  def matches?(req)
    @default || req.headers['Accept'].include?("application/vnd.example.v#{@version}")
  end
end

config/routes.rbমত সেটআপ

require 'api_constraints'

Rails.application.routes.draw do

  # Squads API
  namespace :api do
    # ApiConstaints is a lib file to allow default API versions,
    # this will help prevent having to change link names from /api/v1/squads to /api/squads, better maintainability
    scope module: :v1, constraints: ApiConstraints.new(version:1, default: true) do
      resources :squads do
        # my stuff was here
      end
    end
  end

  resources :squads
  root to: 'site#index'

আপনার নিয়ামক (যেমন /controllers/api/v1/squads_controller.rb) সম্পাদনা করুন

module Api
  module V1
    class SquadsController < BaseController
      # my stuff was here
    end
  end
end

আমি তোমাদের কাছ থেকে আপনার অ্যাপে সমস্ত লিঙ্কের পরিবর্তন করতে পারেন /api/v1/squadsকরতে /api/squadsএবং আপনি পারেন সহজেই এমনকি লিঙ্ক পরিবর্তন না করেও নতুন API সংস্করণ বাস্তবায়ন

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