Phoenix-kehys on kasvanut suosionsa kanssa nopeasti, tarjoten Ruby on Railsin kaltaisten kehysten tuottavuuden samalla kun se on yksi nopeimmat kehykset saatavilla. Se rikkoo myytin, jonka mukaan sinun täytyy uhrata suorituskyky tuottavuuden lisäämiseksi.
Joten mikä on Phoenix?
Phoenix on verkkokehys, joka on rakennettu Elixir-ohjelmointikielellä. Erlang VM: lle rakennettua eliksiiria käytetään matalaviiveisten, vikasietoisten, hajautettujen järjestelmien rakentamiseen, jotka ovat yhä välttämättömimpiä ominaisuuksia nykyaikaisissa verkkosovelluksissa. Voit oppia lisää Elixiristä osoitteesta tämä blogiviesti tai heidän virallinen opas .
Jos olet Ruby on Rails -kehittäjä , sinun tulisi ehdottomasti kiinnostaa Phoenixia lupaamiesi suorituskyvyn takia. Muiden kehysten kehittäjät voivat myös seurata, kuinka Phoenix lähestyy verkkokehitystä.
Tässä artikkelissa opimme joitain asioita Phoenixissa, jotka kannattaa pitää mielessä, jos tulet Ruby on Rails -maailmasta.
Toisin kuin Ruby, Elixir on toiminnallinen ohjelmointikieli, mikä on luultavasti suurin ero, jonka kanssa joudut ehkä kohtaamaan. Näiden kahden alustan välillä on kuitenkin joitain keskeisiä eroja, jotka kaikkien Phoenixia oppivien tulisi olla tietoisia tuottavuutensa maksimoimiseksi.
Tämä on pieni, mutta se on helppo sekoittaa, jos tulet Ruby on Rails -kadulta.
Phoenixissa tapana on kirjoittaa kaikki yksikkömuodossa. Joten sinulla olisi 'UserController' 'UsersController': n sijaan, kuten sinulla olisi Ruby on Rails -sovelluksessa. Tämä pätee kaikkialle paitsi nimettäessä tietokantataulukoita, joissa käytäntö on nimetä taulukko monikkomuodossa.
Tämä ei ehkä näytä kovin suurelta sen jälkeen, kun on oppinut milloin ja missä käyttää monikkomuotoa Ruby on Rails -sovelluksessa, mutta se oli aluksi hieman hämmentävä, kun opettelin käyttämään Ruby on Rails -sovellusta, ja olen varma, että se on sekoittanut monet muutkin. Phoenix antaa sinulle yhden huolenaiheen vähemmän.
Phoenix ja Ruby on Rails ovat hyvin samankaltaisia reitityksen suhteen. Tärkein ero on siinä, miten voit hallita pyynnön käsittelyä.
Ruby on Rails -ohjelmassa (ja muissa Rack-sovelluksissa) tämä tapahtuu väliohjelmiston kautta, kun taas Phoenixissa tämä tapahtuu niin kutsuttujen pistokkeiden avulla.
Pistokkeet ovat mitä käytät yhteyden käsittelyyn.
Esimerkiksi väliohjelmisto Rails::Rack::Logger
kirjaa pyynnön Rails-tiedostoon, joka Phoenixissa suoritettaisiin Plug.Logger
: lla pistoke. Periaatteessa kaikki mitä voit tehdä Rack-väliohjelmistossa, voidaan tehdä pistokkeilla.
Tässä on esimerkki reitittimestä Phoenixissa:
defmodule HelloWorld.Router do use HelloWorld.Web, :router pipeline :browser do plug :accepts, ['html'] plug :fetch_session plug :fetch_flash plug :protect_from_forgery plug :put_secure_browser_headers end pipeline :api do plug :accepts, ['json'] end scope '/', HelloWorld do pipe_through :browser get '/', HelloController, :index end scope '/api', HelloWorld do pipe_through :api end end
Tarkastellaan ensin putkistoja.
Nämä ovat liittimien ryhmiä, joiden kautta pyyntö kulkee. Ajattele sitä väliohjelmistopinona. Niitä voidaan käyttää esimerkiksi sen varmistamiseen, että pyyntö odottaa HTML-koodia, noudata istuntoa ja varmista, että pyyntö on suojattu. Tämä kaikki tapahtuu ennen ohjaimeen pääsyä.
Koska voit määrittää useita putkistoja, voit valita ja valita, mitkä liittimet ovat tarpeen tietyille reiteille. Esimerkiksi reitittimessämme meillä on erilainen putki sivuja (HTML) ja API (JSON) koskevia pyyntöjä varten.
Ei ole aina järkevää käyttää täsmälleen samaa putkea erityyppisiin pyyntöihin. Phoenix antaa meille tämän joustavuuden.
Näkymät Phoenixissa eivät ole samat kuin Ruby on Rails -näkymät.
Phoenixin näkymät vastaavat mallien hahmontamisesta ja toimintojen tarjoamisesta, jotka helpottavat raakatietojen käyttöä mallien käytössä. Näkymä Phoenixissa muistuttaa lähinnä auttajaa Ruby on Rails -sovelluksessa lisäämällä mallin renderoinnin.
Kirjoitetaan esimerkki, joka näyttää 'Hei, maailma!' selaimessa.
app / controllers / hello_controller.rb:
class HelloController app / views / hello / index.html.erb:
') end end
Voit poistaa mallin ja käyttää uutta renderöintitoimintoa, niin saat saman tuloksen. Tämä on hyödyllistä, kun haluat vain palauttaa tekstin tai jopa JSON: n.
Mallit ovat juuri sitä: tietomallit.
Phoenixissa mallit käsittelevät ensisijaisesti tietojen validointia, sen kaavaa, suhteita muihin malleihin ja esitystapaa.
Mallin määrittäminen malliin saattaa kuulostaa aluksi oudolta, mutta sen avulla voit luoda helposti virtuaalikenttiä, jotka ovat kenttiä, joita ei säilytetä tietokannassa. Katsotaanpa esimerkkiä:
defmodule HelloPhoenix.User do use HelloPhoenix.Web, :model schema 'users' do field :name, :string field :email, :string field :password, :string, virtual: true field :password_hash, :string end end
Tässä määritetään neljä kenttää 'käyttäjät' -taulukossa: nimi, sähköpostiosoite, salasana ja password_hash.
Tässä ei ole paljon mielenkiintoista, lukuun ottamatta 'salasana' -kenttää, joka on asetettu 'virtuaaliseksi'.
Näin voimme asettaa ja saada tämän kentän tallentamatta muutoksia tietokantaan. Se on hyödyllinen, koska meillä olisi logiikkaa muuntaa salasana hashiksi, jonka tallennamme 'password_hash' -kenttään ja sitten tallennamme sen tietokantaan.
Sinun on vielä luotava siirto; mallin mallia tarvitaan, koska kenttiä ei ladata automaattisesti malliin, kuten Ruby on Rails -sovelluksessa.
Ero Phoenixin ja Ruby on Railsin välillä on, että malli ei käsittele tietokannan pysyvyyttä. Tätä hoitaa moduuli nimeltä Repo, joka on määritetty tietokantatiedoilla, kuten alla olevassa esimerkissä esitetään:
config :my_app, Repo, adapter: Ecto.Adapters.Postgres, database: 'ecto_simple', username: 'postgres', password: 'postgres', hostname: 'localhost'
Tämä koodi sisältyy ympäristökohtaisiin kokoonpanotiedostoihin, kuten config/dev.exs
tai config/test.exs
. Tämän avulla voimme käyttää Repoa tietokantatoimintojen, kuten luomisen ja päivittämisen, suorittamiseen.
Repo.insert(%User{name: 'John Smith', example: ' [email protected] '}) do {:ok, user} -> # Insertion was successful {:error, changeset} -> # Insertion failed end
Tämä on yleinen esimerkki ohjaimista Phoenixissa.
Annamme Käyttäjälle nimen ja sähköpostin, ja Repo yrittää luoda uuden tietueen tietokantaan. Voimme sitten vaihtoehtoisesti käsitellä onnistunutta tai epäonnistunutta yritystä esimerkissä esitetyllä tavalla.
Jotta ymmärtäisit tämän koodin paremmin, sinun on ymmärrettävä kuvion sovitus Elixirissä. Funktion palauttama arvo on kaksinkertainen. Funktio palauttaa kaksi arvoa, tilan ja sitten joko mallin tai muutosjoukon. Vaihtojoukko on tapa seurata muutoksia ja vahvistaa malli (muutosjoukkoja käsitellään seuraavassa osassa).
Ensimmäinen ylhäältä alaspäin oleva sekoitus, joka vastaa funktion palauttamaa mallia, joka yritti lisätä käyttäjää tietokantaan, suorittaa määritetyn toiminnon.
Olisimme voineet asettaa tilalle muuttujan atomin sijaan (mikä on pohjimmiltaan symboli Ruby'ssa), mutta sitten sovittaisimme sekä onnistuneet että epäonnistuneet yritykset ja käyttäisimme samaa toimintoa molemmissa tilanteissa. Määrittelemällä, minkä atomin haluamme sovittaa, määritämme toiminnon nimenomaan tälle tilalle.
Ruby on Rails -sovelluksella on malliin sisäänrakennettu pysyvyystoiminto ActiveRecordin kautta. Tämä lisää malliin enemmän vastuuta ja voi joskus tehdä mallin testaamisesta monimutkaisemman. Phoenixissa tämä on erotettu tavalla, joka on järkevää ja estää jokaisen mallin turvotuksen pysyvyyslogiikalla.
Muutosjoukot mahdollistavat selkeät validointi- ja muuntosäännöt.
Ruby on Rails -sovelluksessa tietojen vahvistaminen ja muuntaminen voi olla vaikeasti löydettävien virheiden lähde. Tämä johtuu siitä, että se ei ole heti ilmeinen, kun tietoja muunnetaan takaisinsoittojen, kuten 'ennen_luo' ja validointien, avulla.
Phoenixissa teet nimenomaisesti nämä tarkistukset ja muunnokset käyttämällä muutosjoukkoja. Tämä on yksi suosikkini ominaisuuksista Phoenixissa.
Katsotaanpa muutosjoukko lisäämällä yksi edelliseen malliin:
defmodule HelloPhoenix.User do use HelloPhoenix.Web, :model schema 'users' do field :name, :string field :email, :string field :password, :string, virtual: true field :password_hash, :string end def changeset(struct, params \ %{}) do struct |> cast(params, [:name, :email, :password]) |> validate_required([:email, :password]) end end
Tässä muutossarja tekee kaksi asiaa.
Ensinnäkin se kutsuu 'cast' -toiminnon, joka on sallittujen kenttien sallittujen luettelo, samanlainen kuin 'strong_parameters' Ruby on Rails -ohjelmassa, ja sitten se vahvistaa, että 'email' ja 'password' kentät sisältyvät, jolloin 'name' -kenttä valinnainen. Tällä tavalla käyttäjät voivat muokata vain sallimiasi kenttiä.
Tämän lähestymistavan mukava asia on, että emme ole rajoittuneet yhteen muutosryhmään. Voimme luoda useita muutosjoukkoja. Rekisteröinnin muutosryhmä ja käyttäjän päivittäminen ovat yleisiä. Ehkä haluamme vaatia salasanakentän vain rekisteröityessä, mutta emme päivitettäessä käyttäjää.
Vertaa tätä lähestymistapaa siihen, mitä yleensä tehdään Ruby on Rails -sovelluksessa, sinun on määritettävä, että vahvistus tulisi suorittaa vain 'luo' -palvelussa. Tämän vuoksi Railsilla on joskus vaikeaa selvittää, mitä koodisi tekee, kun sinulla on monimutkainen malli.
Toimintojen tuominen on suoraviivaista, mutta joustavaa.
Suuri osa Ecto-kirjaston toiminnallisuudesta tuodaan malleihin. Mallit ovat yleensä tämän linjan lähellä yläosaa:
use HelloPhoenix.Web, :model
”HelloPhoenix.Web” -moduuli sijaitsee osoitteessa ”web / web.ex”. Moduulissa pitäisi olla toiminto nimeltä 'malli' seuraavasti:
def model do quote do use Ecto.Schema import Ecto import Ecto.Changeset import Ecto.Query end end
Täältä näet mitä moduuleja tuomme Ectosta. Voit poistaa tai lisätä kaikki muut haluamasi moduulit täältä ja ne tuodaan kaikkiin malleihin.
On myös samanlaisia toimintoja, kuten 'näkymä' ja 'ohjain', jotka palvelevat samaa tarkoitusta vastaavasti näkymille ja ohjaimille.
quote
ja use
avainsanat saattavat tuntua hämmentäviltä. Tässä esimerkissä voit ajatella tarjouksen suorittavan kyseisen koodin suoraan sen toiminnon kutsuvan moduulin yhteydessä. Joten se vastaa koodin kirjoittamista lainauksen sisälle moduuliin.
Use-avainsanalla voit myös suorittaa koodin missä sitä kutsutaan. Se vaatii olennaisesti määritetyn moduulin ja kutsuu sitten __using__
makro moduulissa, jossa se toimii, missä sitä kutsuttiin. Voit lukea lisää lainata ja käyttää virallisessa oppaassa.
Tämä todella auttaa sinua ymmärtämään, missä tietyt toiminnot sijaitsevat kehyksessä, ja vähentää tunnetta, että kehys tekee paljon 'taikuutta'.
Samanaikaisuus on ytimessä.
Samanaikaisuus tulee ilmaiseksi Phoenixissa, koska se on Elixirin pääominaisuus. Saat sovelluksen, joka voi luoda useita prosesseja ja suorittaa useita ytimiä huolimatta langan turvallisuudesta ja luotettavuudesta.
Voit synnyttää uuden prosessin Elixirissä tällä tavalla:
spawn fn -> 1 + 2 end
Kaikki sen jälkeen spawn
ja ennen end
suoritetaan uudessa prosessissa.
Itse asiassa kaikki Phoenixin pyynnöt käsitellään omassa prosessissaan. Elixir käyttää Erlang VM: n voimaa tuodakseen luotettavan ja tehokkaan samanaikaisuuden 'ilmaiseksi'.
Tämä tekee myös Phoenixista erinomaisen valinnan WebSocketia käyttävien palvelujen suorittamiseen, koska WebSocketsin on ylläpidettävä avointa yhteyttä asiakkaan ja palvelimen välillä (mikä tarkoittaa, että sinun on rakennettava sovelluksesi siten, että se pystyy käsittelemään mahdollisesti tuhansia samanaikaisia yhteyksiä).
Nämä vaatimukset lisäävät paljon monimutkaisuutta Ruby on Rails -sovellukseen rakennettuun projektiin, mutta Phoenix voi täyttää nämä vaatimukset ilmaiseksi Elixirin kautta.
Jos haluat käyttää WebSocketsia Phoenix-sovelluksessasi, sinun on käytettävä sitä Kanavat . Se vastaa ActionCable
Ruby on Rails -sovelluksessa, mutta määritys on vähemmän monimutkaista, koska sinun ei tarvitse käyttää erillistä palvelinta.
Phoenix tekee nykyaikaisten verkkosovellusten rakentamisesta kivutonta.
Vaikka olemme keskittyneet suurelta osin eroihin, Phoenixilla on kuitenkin joitakin yhteisiä asioita Ruby on Railsin kanssa.
Phoenix noudattaa suunnilleen samaa MVC-mallia kuin Ruby on Rails, joten mihin koodiin menemisen ei pitäisi olla vaikeaa nyt, kun tiedät tärkeimmistä eroista. Phoenixilla on myös samanlaisia generaattoreita kuin Ruby on Rails mallien, ohjainten, siirtojen ja muun luomiseen.
Kun olet oppinut Elixirin, lähestyt hitaasti Ruby on Rails -tuotantotasoa, kun olet mukavampi Phoenixin kanssa.
Muutama kerta, kun en tunne olevani yhtä tuottava, on se, että kohtaan ongelman, jonka Rubyn helmi ratkaisi, enkä löydä vastaavaa kirjastoa Elixirille. Onneksi kasvavat eliksiiriyhteisöt täyttävät nämä aukot hitaasti.
Phoenixin erot auttavat ratkaisemaan paljon kipua, joka tuli monimutkaisten Ruby on Rails -projektien hallinnasta. Vaikka ne eivät ratkaise kaikkia asioita, ne auttavat ajamaan sinut oikeaan suuntaan. Hidas kehys, koska haluat tuottavuuden, ei ole enää kelvollinen tekosyy, Phoenix antaa sinulle molemmat.