1 Kas yra API programa?
Tradiciškai, kai žmonės sakė, kad jie naudoja „Rails“ kaip „API“, jie turėjo omenyje programiškai pasiekiamą API, kartu su savo internetinės programos. Pavyzdžiui, „GitHub“ teikia API, kurį galite naudoti savo asmeniniuose klientuose.
Su kliento pusės karkasais atėjimu, vis daugiau programuotojų naudoja „Rails“ kurti pagrindinę dalį, kuri bendrinama tarp jų internetinės programos ir kitų natyvinių programų.
Pavyzdžiui, „Twitter“ savo internetinėje programoje naudoja savo viešą API, kuri yra sukuriama kaip statinė svetainė, kuri naudoja JSON išteklius.
Vietoje to, kad „Rails“ generuotų HTML, kuris bendrauja su serveriu per formą ir nuorodas, daugelis programuotojų savo internetinę programą traktuoja kaip tik API klientą, kuris pristatomas kaip HTML su JavaScript, kuris naudoja JSON API.
Šiame vadove aprašoma, kaip sukurti „Rails“ programą, kuri teikia JSON išteklius API klientui, įskaitant kliento pusės karkasus.
2 Kodėl naudoti „Rails“ JSON API?
Pirma klausimas, kurį daugelis žmonių turi, galvodami apie JSON API kūrimą naudojant „Rails“, yra: „ar naudoti „Rails“ tik tam, kad išspausdintų JSON? Ar neturėčiau tiesiog naudoti kažko panašaus į „Sinatra“?“.
Labai paprastoms API tai gali būti tiesa. Tačiau net labai daug HTML turinčiose programose, didžioji dalis programos logikos yra už žiūrimojo sluoksnio ribų.
Pagrindinė priežastis, kodėl daugelis žmonių naudoja „Rails“, yra tai, kad jis teikia numatytąjį rinkinį parametrų, kurie leidžia programuotojams greitai pradėti dirbti, nereikalaujant priimti daugybės trivialių sprendimų.
Pažvelkime į keletą dalykų, kuriuos „Rails“ numato iš anksto ir kurie vis dar yra taikomi API programoms.
Tvarkomi tarpinės programinės įrangos sluoksnyje:
- Persikrovimas: „Rails“ programos palaiko skaidrų persikrovimą. Tai veikia net jei jūsų programa tampa didelė ir kiekvienam užklausos persikrovimas tampa neįmanomas.
- Plėtojimo režimas: „Rails“ programos turi protingus numatytuosius nustatymus plėtojimui, padarant plėtojimą malonų, nesutrikdant gamybos metu našumo.
- Testavimo režimas: Taip pat kaip ir plėtojimo režimas.
- Žurnalavimas: „Rails“ programos žurnaloja kiekvieną užklausą, su tam tikru išsamumu atitinkamu dabartiniam režimui. „Rails“ žurnale plėtojimo metu yra informacija apie užklausos aplinką, duomenų bazės užklausas ir pagrindinę našumo informaciją.
- Saugumas: „Rails“ aptinka ir neleidžia IP klastojimo atakoms ir tvarko kriptografinius parašus laiko atakose sąmoningas. Nežinote, kas yra IP klastojimo ataka ar laiko ataka? Būtent.
- Parametrų analizavimas: Norite nurodyti parametrus kaip JSON, o ne kaip
URL užkoduotą eilutę? Nėra problema. „Rails“ jį jums iškoduos ir padarys
jį prieinamą
params
kintamajame. Norite naudoti įdėtus URL užkoduotus parametrus? Tai taip pat veikia. - Sąlyginiai GET užklausos: „Rails“ tvarko sąlyginę
GET
(ETag
irLast-Modified
) apdorojimą užklausos antraštėse ir grąžina teisingas atsakymo antraštes ir būsenos kodą. Viskas, ką jums reikia padaryti, tai naudotistale?
tikrinimą savo valdiklyje, ir „Rails“ visais HTTP detaliais užsiims už jus. - HEAD užklausos: „Rails“ automatiškai konvertuos
HEAD
užklausas įGET
užklausas, ir grąžins tik antraštes. Tai padaro, kadHEAD
užklausa patikimai veiktų visose „Rails“ API.
Nors aišku, galėtumėte tai sukurti naudodami esamą „Rack“ tarpinės programinės įrangos sluoksnį, šis sąrašas parodo, kad numatytasis „Rails“ tarpinės programinės įrangos rinkinys teikia daug naudos, net jei jūs „tiesiog generuojate JSON“.
Tvarkoma „Action Pack“ sluoksnyje:
- Resursų maršrutizavimas: Jei kuriate RESTful JSON API, norite naudoti „Rails“ maršrutizatorių. Švarus ir konvencinis atvaizdavimas nuo HTTP iki valdiklių reiškia, kad nereikia gaišti laiko galvojant, kaip modeliuoti savo API pagal HTTP.
- URL generavimas: Maršrutizavimo atvirkštinė pusė yra URL generavimas. Geras HTTP pagrindu veikiantis API apima URL (žr. „GitHub Gist API“ pavyzdį).
- Antraščių ir peradresavimo atsakymai:
head :no_content
irredirect_to user_url(current_user)
naudingi. Žinoma, galėtumėte rankiniu būdu pridėti atsakymo antraštes, bet kodėl? - Talpinimas: „Rails“ teikia puslapio, veiksmo ir fragmento talpinimą. Fragmento talpinimas ypač naudingas, kuriant įdėtą JSON objektą.
- Pagrindinis, viršūninis ir žetonų autentifikavimas: „Rails“ iš karto palaiko tris HTTP autentifikavimo rūšis.
- Instrumentavimas: „Rails“ turi instrumentavimo API, kuris sukelia užregistruotus tvarkytojus įvairioms įvykių rūšims, pvz., veiksmo apdorojimui, failo siuntimui ar duomenims, peradresavimui ir duomenų bazės užklausoms. Kiekvieno įvykio duomenų srautas ateina su atitinkama informacija (veiksmo apdorojimo įvykiui, duomenų sraute yra valdiklis, veiksmas, parametrai, užklausos formatas, užklausos metodas ir užklausos pilnas kelias).
- Generatoriai: Dažnai patogu generuoti išteklių ir gauti savo modelį, valdiklį, testavimo šablonus ir maršrutus, kurie yra sukurti vienu komandos įvedimu, kad būtų galima juos toliau keisti. Taip pat ir migracijoms ir kt.
- Įskiepiai: Daugelis trečiųjų šalių bibliotekų palaiko „Rails“, kuris sumažina
arba pašalina bibliotekos ir internetinio karkaso sąnaudas. Tai apima dalykus, tokie kaip numatytųjų generatorių perrašymas, papildomų Rake užduočių pridėjimas ir „Rails“ pasirinkimų laikymas (pvz., žurnalizatorius ir talpyklos pagrindas).
Žinoma, "Rails" paleidimo procesas taip pat sujungia visus užregistruotus komponentus.
Pavyzdžiui, "Rails" paleidimo procesas naudoja jūsų
config/database.yml
failą, konfigūruojant "Active Record".
Trumpa versija yra: galbūt nesvarstėte, kurie "Rails" komponentai vis dar yra taikomi, net jei pašalinate rodinio sluoksnį, tačiau atsakymas iš esmės yra - dauguma jų.
3 Pagrindinė konfigūracija
Jei kuriate "Rails" aplikaciją, kuri pirmiausia bus API serveris, galite pradėti su ribotesniu "Rails" rinkiniu ir pridėti funkcijas, kai reikia.
3.1 Naujos aplikacijos kūrimas
Galite sukurti naują API "Rails" aplikaciją:
$ rails new my_api --api
Tai jums padarys tris pagrindines veiklas:
- Konfigūruos jūsų aplikaciją pradėti su ribotesniu middleware rinkiniu nei įprasta. Konkrečiai, pagal numatytuosius nustatymus ji neįtrauks jokio middleware, kuris yra pagrindinai naudingas naršyklės aplikacijoms (pvz., slapukų palaikymas).
- Padarys, kad
ApplicationController
paveldėtųActionController::API
, o neActionController::Base
. Kaip ir su middleware, tai paliks bet kokius Action Controller modulius, kurie teikia funkcijas, daugiausia naudojamas naršyklės aplikacijoms. - Konfigūruos generatorius praleisti generuojant rodinius, pagalbininkus ir išteklius, kai generuojate naują išteklių.
3.2 Naujo ištekliaus generavimas
Norėdami pamatyti, kaip mūsų naujai sukurta API tvarko naujo ištekliaus generavimą, sukurkime naują grupės išteklių. Kiekviena grupė turės pavadinimą.
$ bin/rails g scaffold Group name:string
Prieš galėdami naudoti mūsų sugeneruotą kodą, turime atnaujinti duomenų bazės schemą.
$ bin/rails db:migrate
Dabar, jei atidarome GroupsController
, turėtume pastebėti, kad su API "Rails" aplikacija mes rodoma tik JSON duomenis. Indeksų veiksmo metu užklausime Group.all
ir priskirsime ją kintamajam, vadinamam @groups
. Pervestas į render
su :json
parinktimi, grupės automatiškai bus rodomos kaip JSON.
# app/controllers/groups_controller.rb
class GroupsController < ApplicationController
before_action :set_group, only: %i[ show update destroy ]
# GET /groups
def index
@groups = Group.all
render json: @groups
end
# GET /groups/1
def show
render json: @group
end
# POST /groups
def create
@group = Group.new(group_params)
if @group.save
render json: @group, status: :created, location: @group
else
render json: @group.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /groups/1
def update
if @group.update(group_params)
render json: @group
else
render json: @group.errors, status: :unprocessable_entity
end
end
# DELETE /groups/1
def destroy
@group.destroy
end
private
# Use callbacks to share common setup or constraints between actions.
def set_group
@group = Group.find(params[:id])
end
# Only allow a list of trusted parameters through.
def group_params
params.require(:group).permit(:name)
end
end
Galų gale galime pridėti keletą grupių į mūsų duomenų bazę iš "Rails" konsolės:
irb> Group.create(name: "Rails Founders")
irb> Group.create(name: "Rails Contributors")
Turėdami kai kuriuos duomenis aplikacijoje, galime paleisti serverį ir aplankyti http://localhost:3000/groups.json, kad pamatytume mūsų JSON duomenis.
[
{"id":1, "name":"Rails Founders", "created_at": ...},
{"id":2, "name":"Rails Contributors", "created_at": ...}
]
3.3 Esamos aplikacijos keitimas
Jei norite paimti esamą aplikaciją ir ją paversti API aplikacija, perskaitykite šiuos žingsnius.
config/application.rb
faile, pridėkite šią eilutę virš Application
klasės apibrėžimo:
config.api_only = true
config/environments/development.rb
faile, nustatykite config.debug_exception_response_format
konfigūruoti formatą, naudojamą atsakymuose, kai klaidos įvyksta vystymo režimu.
Norint atvaizduoti HTML puslapį su derinimo informacija, naudokite reikšmę :default
.
config.debug_exception_response_format = :default
Norint atvaizduoti derinimo informaciją išlaikant atsakymo formatą, naudokite reikšmę :api
.
config.debug_exception_response_format = :api
Pagal numatytuosius nustatymus, kai config.api_only
nustatoma kaip true
, config.debug_exception_response_format
nustatoma kaip :api
.
Galų gale, app/controllers/application_controller.rb
faile, vietoj:
class ApplicationController < ActionController::Base
end
padarykite:
class ApplicationController < ActionController::API
end
4 Middleware pasirinkimas
API aplikacija pagal numatytuosius nustatymus turi šiuos middleware:
ActionDispatch::HostAuthorization
Rack::Sendfile
ActionDispatch::Static
ActionDispatch::Executor
ActionDispatch::ServerTiming
ActiveSupport::Cache::Strategy::LocalCache::Middleware
Rack::Runtime
ActionDispatch::RequestId
ActionDispatch::RemoteIp
Rails::Rack::Logger
ActionDispatch::ShowExceptions
ActionDispatch::DebugExceptions
ActionDispatch::ActionableExceptions
ActionDispatch::Reloader
ActionDispatch::Callbacks
ActiveRecord::Migration::CheckPending
Rack::Head
Rack::ConditionalGet
Rack::ETag
Daugiau informacijos apie juos rasite vidinio middleware skyriuje "Rack" vadove.
Kiti įskiepiai, įskaitant "Active Record", gali pridėti papildomų middleware. Bendrai, šie middleware yra neutralūs atžvilgiu jūsų kuriamos aplikacijos tipo ir tinka tik API tik "Rails" aplikacijoms. Jūs galite gauti visų middleware sąrašą savo aplikacijoje naudodami:
$ bin/rails middleware
4.1 Naudodami Rack::Cache
Kai naudojamas su Rails, Rack::Cache
naudoja Rails talpyklą savo
entiteto ir metaduomenų talpykloms. Tai reiškia, kad jei naudojate memcache savo
Rails aplikacijai, pavyzdžiui, įmontuota HTTP talpykla naudos memcache.
Norėdami naudoti Rack::Cache
, pirmiausia turite pridėti rack-cache
gemą
į Gemfile
, ir nustatyti config.action_dispatch.rack_cache
į true
.
Norėdami įgalinti jo funkcionalumą, norėsite naudoti stale?
savo
valdiklyje. Čia pateikiamas stale?
pavyzdys.
def show
@post = Post.find(params[:id])
if stale?(last_modified: @post.updated_at)
render json: @post
end
end
Kviečiant stale?
bus palyginamas If-Modified-Since
antraštė užklausoje
su @post.updated_at
. Jei antraštė naujesnė nei paskutinė modifikacija, ši
veiksmas grąžins "304 Not Modified" atsaką. Kitu atveju, jis atvaizduos
atsaką ir į jį įtrauks Last-Modified
antraštę.
Įprastai šis mechanizmas naudojamas atskirai kiekvienam klientui. Rack::Cache
leidžia mums bendrinti šį talpinimo mechanizmą tarp klientų. Galime įgalinti
talpinimą tarp klientų kviečiant stale?
:
def show
@post = Post.find(params[:id])
if stale?(last_modified: @post.updated_at, public: true)
render json: @post
end
end
Tai reiškia, kad Rack::Cache
saugos Last-Modified
reikšmę
URL adresui Rails talpykloje ir pridės If-Modified-Since
antraštę bet kokiai
tolimesnei užklausai to pačio URL adreso.
Galima sakyti, kad tai yra puslapio talpinimas naudojant HTTP semantiką.
4.2 Naudodami Rack::Sendfile
Kai naudojate send_file
metodą viduje Rails valdiklio, jis nustato
X-Sendfile
antraštę. Rack::Sendfile
yra atsakingas už faktinį failo siuntimo
darbą.
Jei jūsų priekinio serverio palaiko pagreitintą failo siuntimą, Rack::Sendfile
perduos faktinį failo siuntimo darbą priekiniam serveriui.
Galite konfigūruoti antraštės pavadinimą, kurį jūsų priekinio serverio naudoja
šiam tikslui, naudodami config.action_dispatch.x_sendfile_header
tinkamoje
konfigūracijos failo aplinkoje.
Daugiau informacijos apie tai, kaip naudoti Rack::Sendfile
su populiariais
priekiniais serveriais, rasite Rack::Sendfile
dokumentacijoje.
Čia pateikiamos kai kurių populiarių serverių šios antraštės reikšmės, kai šie serveriai yra sukonfigūruoti palaikyti pagreitintą failo siuntimą:
# Apache ir lighttpd
config.action_dispatch.x_sendfile_header = "X-Sendfile"
# Nginx
config.action_dispatch.x_sendfile_header = "X-Accel-Redirect"
Įsitikinkite, kad sukonfigūravote savo serverį, kad jis palaikytų šias parinktis, vadovaudamiesi
Rack::Sendfile
dokumentacijoje pateiktais nurodymais.
4.3 Naudodami ActionDispatch::Request
ActionDispatch::Request#params
priims kliento parametrus JSON
formate ir prieinamus jūsų valdiklyje params
.
Norėdami tai naudoti, jūsų klientui reikės pateikti užklausą su JSON koduotais parametrais
ir nurodyti Content-Type
kaip application/json
.
Čia pateikiamas pavyzdys naudojant jQuery:
jQuery.ajax({
type: 'POST',
url: '/people',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify({ person: { firstName: "Yehuda", lastName: "Katz" } }),
success: function(json) { }
});
ActionDispatch::Request
pamatys Content-Type
ir jūsų parametrai
bus:
{ person: { firstName: "Yehuda", lastName: "Katz" } }
4.4 Naudodami sesijos middleware
Šie middleware, naudojami sesijų valdymui, yra neįtraukti į API aplikacijas, nes jos paprastai nenaudoja sesijų. Jei vienas iš jūsų API klientų yra naršyklė, galbūt norėsite pridėti vieną iš šių atgal:
ActionDispatch::Session::CacheStore
ActionDispatch::Session::CookieStore
ActionDispatch::Session::MemCacheStore
Būdas pridėti juos atgal yra toks, kad pagal numatytuosius nustatymus, jiems perduodami session_options
kai pridedami (įskaitant sesijos raktą), todėl negalite tiesiog pridėti session_store.rb
inicializavimo failo, pridėti
use ActionDispatch::Session::CookieStore
ir sesijos veikimas kaip įprasta. (Norint aiškiai pasakyti: sesijos
gali veikti, bet jūsų sesijos parinktys bus ignoruojamos - t. y. sesijos raktas bus numatytasis _session_id
)
Vietoje inicializatoriaus, turėsite nustatyti atitinkamus nustatymus kažkur prieš jūsų middleware yra
sukurta (pvz., config/application.rb
) ir perduoti juos pageidaujamam middleware, kaip čia:
# Tai taip pat konfigūruoja session_options naudojimui žemiau
config.session_store :cookie_store, key: '_interslice_session'
# Reikalinga visiems sesijos valdymui (nesvarbu, kokio tipo session_store)
config.middleware.use ActionDispatch::Cookies
config.middleware.use config.session_store, config.session_options
4.5 Kiti middleware
Rails pristato keletą kitų middleware, kuriuos galbūt norėsite naudoti API aplikacijoje, ypač jei vienas iš jūsų API klientų yra naršyklė:
Rack::MethodOverride
ActionDispatch::Cookies
ActionDispatch::Flash
Bet kurį iš šių middleware galima pridėti naudojant:
config.middleware.use Rack::MethodOverride
4.6 Middleware pašalinimas
Jei nenorite naudoti middleware, kuris yra įtrauktas pagal numatytuosius nustatymus API tik
middleware rinkinyje, jį galite pašalinti naudodami:
ruby
config.middleware.delete ::Rack::Sendfile
Atkreipkite dėmesį, kad pašalinus šiuos middleware'us, bus pašalinta palaikymas tam tikroms funkcijoms veikiant Action Controller.
5 Pasirinkimas kontrolerio moduliams
API programa (naudojanti ActionController::API
) pagal numatytuosius nustatymus turi šiuos kontrolerio modulius:
ActionController::UrlFor |
Leidžia naudoti url_for ir panašius pagalbininkus. |
ActionController::Redirecting |
Palaikymas redirect_to . |
AbstractController::Rendering ir ActionController::ApiRendering |
Pagrindinis atvaizdavimo palaikymas. |
ActionController::Renderers::All |
Palaikymas render :json ir panašiems veiksmams. |
ActionController::ConditionalGet |
Palaikymas stale? . |
ActionController::BasicImplicitRender |
Užtikrina tuščią atsaką, jei nėra aiškaus atsakymo. |
ActionController::StrongParameters |
Parametrų filtravimo palaikymas, derinant su Active Model masinio priskyrimo. |
ActionController::DataStreaming |
Palaikymas send_file ir send_data . |
AbstractController::Callbacks |
Palaikymas before_action ir panašiems pagalbininkams. |
ActionController::Rescue |
Palaikymas rescue_from . |
ActionController::Instrumentation |
Palaikymas veiksmų kontrolerio apibrėžtoms instrumentacijos kabliukams (daugiau informacijos apie tai rasite instrumentacijos vadove). |
ActionController::ParamsWrapper |
Apvija parametrų hash į įdėtą hash'ą, todėl nereikia nurodyti šaknies elementų siunčiant POST užklausas, pvz. |
ActionController::Head |
Palaikymas grąžinti atsakymą be turinio, tik antraštėmis. |
Kiti įskiepiai gali pridėti papildomus modulius. Galite gauti visų modulių sąrašą, įtrauktų į ActionController::API
, naudodami "rails console":
irb> ActionController::API.ancestors - ActionController::Metal.ancestors
=> [ActionController::API,
ActiveRecord::Railties::ControllerRuntime,
ActionDispatch::Routing::RouteSet::MountedHelpers,
ActionController::ParamsWrapper,
... ,
AbstractController::Rendering,
ActionView::ViewPaths]
5.1 Kitų modulių pridėjimas
Visi veiksmų kontrolerio moduliai žino apie savo priklausomus modulius, todėl galite laisvai įtraukti bet kokius modulius į savo kontrolerius, ir visi priklausomybės bus įtrauktos ir nustatytos.
Kai kuriuos dažnai naudojamus modulius, kuriuos galite pridėti:
AbstractController::Translation
: Palaikymasl
irt
lokalizacijos ir vertimo metodams.- Palaikymas pagrindiniam, viršutiniam arba žetono HTTP autentifikavimui:
ActionController::HttpAuthentication::Basic::ControllerMethods
ActionController::HttpAuthentication::Digest::ControllerMethods
ActionController::HttpAuthentication::Token::ControllerMethods
ActionView::Layouts
: Palaikymas išdėstymams atvaizduojant.ActionController::MimeResponds
: Palaikymasrespond_to
.ActionController::Cookies
: Palaikymascookies
, įskaitant palaikymą pasirašytiems ir užšifruotiems slapukams. Tai reikalauja slapukų middleware.ActionController::Caching
: Palaikymas vaizdo talpinimui API kontroleryje. Atkreipkite dėmesį, kad turėsite rankiniu būdu nurodyti talpyklą kontroleryje, pavyzdžiui:class ApplicationController < ActionController::API include ::ActionController::Caching self.cache_store = :mem_cache_store end
"Rails" nepereina šios konfigūracijos automatiškai.
Geriausia vieta pridėti modulį yra jūsų ApplicationController
, tačiau taip pat galite pridėti modulius prie atskirų kontrolerių.
Atsiliepimai
Jūs esate skatinami padėti pagerinti šio vadovo kokybę.
Prašome prisidėti, jei pastebite rašybos klaidų ar faktinių klaidų. Norėdami pradėti, galite perskaityti mūsų dokumentacijos prisidėjimo skyrių.
Taip pat gali būti nepilnos informacijos arba informacijos, kuri nėra atnaujinta. Prašome pridėti bet kokią trūkstamą dokumentaciją pagrindiniam. Patikrinkite Edge vadovus pirmiausia, ar problemas jau išspręsta arba ne pagrindinėje šakoje. Patikrinkite Ruby on Rails vadovų gaires dėl stiliaus ir konvencijų.
Jei dėl kokios nors priežasties pastebite kažką, ką reikia ištaisyti, bet negalite patys tai pataisyti, prašome pranešti apie problemą.
Ir galiausiai, bet ne mažiau svarbu, bet koks diskusijos dėl Ruby on Rails dokumentacijos yra labai laukiamos oficialiame Ruby on Rails forume.