Nodal:Výukový program pro snadné vytváření služeb API v Node.js

Pokud jste o Nodalu ještě neslyšeli, nebo ho máte, ale nejste si jisti, kde začít, tento návod je pro vás! Ujistěte se, že držíte krok s Nodal na GitHubu, abyste mohli sledovat aktualizace projektu.

Nodal je serverová platforma a rámec Node.js, který vám umožňuje snadno vyvíjet služby API. Vzhledem k tomu, že produkty jsou stále více multiplatformní (web, mobilní zařízení, IoT), musíme začít přemýšlet o naší backendové architektuře pomocí přístupu orientovaného na služby, nikoli jako dodatečného nápadu.

Cílem Nodalu je vytvořit encyklopedii kolem Node.js, která umožní každému vývojáři –  začátečníkovi nebo veteránovi, back-endu nebo front-endu  – zapojit se a začít bez námahy vytvářet webové aplikace.

Nodal má vestavěnou podporu PostgreSQL, často používá moderní idiomy syntaxe ES6 a podporuje poměrně rigidní vzory návrhu softwaru. To umožňuje Nodalto za vás dělat spoustu rozhodnutí, abyste mohli své aplikace postavit a nasadit rychle a s větší jistotou. Pusťte se do psaní kódu, který pohání váš produkt rychleji, a nechte Nodal, ať to zvládne.

I když se základní kompetence Nodalu nepoužívá jako tradiční monolitický webový server, může k tomuto účelu stále používat. Je to mimo rozsah tohoto výukového programu, ale procházením dokumentace budete moci zjistit, jak přimět Nodal, aby dělal, co chcete – sloužil statickému brandingovému webu, podpoře šablon atd.

Náš první uzlový projekt

Zatímco mnoho Nodalu vám bude povědomých, pokud jste dříve pracovali s MVCframework, jako je Django nebo Ruby on Rails, začneme nastavením základního API serveru a vygenerujeme několik modelů. Je dobré začít s ukázkovým projektem, takže pojďme vytvořit klon Twitteru s názvem Instatweet .

Pro referenci můžete najít dokončenou verzi projektu použitého pro tento tutoriál na keithwhor/instatweet-apion GitHub.

Nastavení uzlu

Abychom mohli nainstalovat Nodal a uvést jej do provozu s databází, musíme provést následující:

  1. Nainstalujte Node.js 4.x nebo vyšší
  2. Nainstalujte PostgreSQL
  3. Nainstalujte Nodal

Instalace Node.js

Abyste se ujistili, že používáte nejnovější verzi Node.js, přejděte na Nodejs.org a stáhněte si nejnovější verzi 4.x nebo vyšší. Nodal byl vyvinut výslovně pro 4.x, takže to je to, co se v současnosti doporučuje.

Instalace PostgreSQL

Pokud používáte Mac OS X, důrazně doporučuji použít Postgres.app ke zprovoznění a spuštění PostgreSQL na vašem počítači. Ujistěte se, že jste nakonfigurovali $PATH, abyste získali přístup k nástrojům příkazového řádku. Jakmile je Postgres.app nainstalována a budete postupovat podle pokynů k nastavení CLI, ujistěte se, že existuje uživatel postgressuper s názvem postgres (bez hesla) s:

$ createuser postgres -s

Pro instalaci Windows se můžete podívat na web PostgreSQL.

Instalace Nodal

Jste téměř připraveni začít bleskově nastavovat servery API. :)

Chcete-li nainstalovat Nodal, jednoduše otevřete příkazový řádek terminálu a zadejte:

$ npm install nodal -g

Tím se nainstalují nástroje příkazového řádku Nodal a aktuální verze jádra Nodal. Jste připraveni začít!

Vytvoření vašeho projektu

Nastavení projektu je snadné. Přejděte do adresáře, ve kterém chcete vytvořit složku projektu, a zadejte:

$ nodal new

Zobrazí se výzva...

Welcome to Nodal! v0.7.x
? Název (my-nodal-project)

Můžete si to pojmenovat, jak chcete, ale já budu používat instatweet-api pro tento tutoriál. Budete také požádáni o zadání svého jména. Nodal za vás vytvoří váš projektový adresář a zkopíruje všechny potřebné balíčky (node_modules) z vaší globální instalace nodal.

Spouštění serveru

Spusťte server pomocí:

$ nodal s

Uvidíte něco jako:

[Nodal.Daemon] Startup: Initializing
Initializer Ready
[Nodal.Daemon] Startup: Spawning HTTP Workers
[Nodal.27454] Startup: Starting HTTP Worker
[Nodal.27455] Startup: Starting HTTP Worker
[Nodal.27455] Ready: HTTP Worker listening on port 3000
[Nodal.27454] Ready: HTTP Worker listening on port 3000

Ve skutečnosti uvidíte nový [Nodal.XXXX] proces vytvořený pro každé z jader vašeho procesoru. Takže pokud zde vidíte 16 zpráv (2 pro každé jádro), nebojte se. To jen démon dělá svou práci. :)

Nodal dělá dobrou práci, když se sám restartuje při změnách souborů, takže nechte server spuštěný a otevřete další okno terminálu a přejděte zpět do adresáře projektu yourinstatweet-api.

Vytvoření vašeho prvního modelu

Vytvoření modelu je jednoduché. Spusťte terminál a zadejte:

$ nodal g:model Tweet user_id:int body:string

Uvidíte něco jako:

Create: ./app/models/tweet.js
Create: ./db/migrations/2016022003113671__create_tweet.js

Soubor modelu a migrace byly pro vás automaticky vytvořeny.

Soubor Model obsahuje informace o objektu Tweet ve vašem projektu, který obsahuje celočíselné pole s názvem user_id a tělo, což je řetězec.

Migrační soubor je sada příkazů pro vytvoření tabulky v Postgresdatabase pro uchování dat Tweetů s poli jako sloupce v tabulce.

Vytvoření prvního ovladače

Nyní, když máme model, chceme pro tento model ovladač. Můžeme znovu použít příkazový řádek, abychom to usnadnili:

$ nodal g:controller v1 --for:Tweet

v1 říká nám jmenný prostor a --for:Tweet sděluje nám Controlleris řadič Create-Read-Update-Destroy (CRUD) pro modelový zdroj (některé věci udělá za nás). Všimněte si, že něco jako:

$ nodal g:controller v1/Tweet

je také přijatelné, ale vytvoří prázdnou šablonu Controller bez příkazů CRUD, takže budete muset napsat všechny funkce sami.

Z tohoto příkazu byste měli vidět:

Create: ./app/controllers/v1/tweets_controller.js
Modify: ./app/router.js

Nástroje příkazového řádku Nodal automaticky upravily vaše trasy a vytvořily za vás vaše ovladače. Router automaticky přidal určité standardní cesty a metody HTTP, jako je GET a POST. k poskytování rozhraní API pro tweety – výpis, vytváření, aktualizace, mazání tweetů atd.

Spuštění migrací

Nyní, když máte tweetový model a migraci, než začneme propojovat náš tweetový model, budeme se chtít ujistit, že je databáze připravena jej zpracovat. Vytvořte databázi uvedenou v config/db.json s:

$ nodal db:create

Nyní jej připravte na migraci a poté spusťte tyto migrace pomocí:

$ nodal db:prepare
$ nodal db:migrate

Propojení s našimi tweety

Ujistěte se, že váš server opět běží na localhost s nodal s .

Otevřete http://localhost:3000/v1/tweets ve vašem prohlížeči. Toto je trasa, která byla vytvořena automaticky vytvořením modelu Tweetu. Všimněte si, že jsme model Tweetu automaticky převedli do množného čísla, aby byla trasa „tweety“. Měli byste vidět:

{
  "meta": {
    "total": 0,
    "count": 0,
    "offset": 0,
    "error": null
  },
  "data": []
}

Chcete-li vytvořit tweet, jednoduše odešlete požadavek POST do stejného koncového bodu s daty JSON nebo daty kódovanými urlencode. Můžete použít curl pro tohle. (Vyzkoušejte také Postman Chrome Plugin, vizuální nástroj, který je skvělý pro posouvání dat do az rozhraní API.)

$ curl --data "user_id=1&body=Testing" http://localhost:3000/v1/tweets

Vaše odpověď by měla vypadat nějak takto:

{
  "meta": {
    "total": 1,
    "count": 1,
    "offset": 0,
    "error": null
  },
  "data": [
    {
      "id": 1,
      "user_id": 1,
      "body": "Testing",
      "created_at": "2016-02-20T03:21:30.879Z",
      "updated_at": "2016-02-20T03:21:30.882Z"
    }
  ]
}

Obnovte stránku prohlížeče na http://localhost:3000/v1/tweets a tam byste měli vidět tweet.

Vytvoření uživatelského modelu

Skvělý! Nyní máme tweety, ale chceme nějaké uživatele. Aby bylo možné zvládnout šifrování hesel (abyste ho nemuseli psát sami), Nodal přichází s předpečeným uživatelským modelem, který můžete vygenerovat pomocí:

$ nodal g:model --user

Tento uživatelský model bude generován s username , email a password pole automaticky spolu s bcrypt balíček pro šifrování hesla.

Vygenerujte ovladač pro své uživatelské modely pomocí:

$ nodal g:controller v1 --for:User

Migrujte svou databázi pomocí:

$ nodal db:migrate

Spusťte svůj server s nodal s a odešlete následující požadavek POST na vytvoření uživatele:

$ curl --data "username=test_user&[email protected]&password=password" http://localhost:3000/v1/users

Dostanete odpověď jako:

{
  "meta": {
    "total": 1,
    "count": 1,
    "offset": 0,
    "error": null
  },
  "data": [
    {
      "id": 1,
      "email": "[email protected]",
      "password": "$2a$10$/pXLNrp9afneJtImvNTBO.79CIsd8N39fko4sF3CaXZyoaxpctQZS",
      "username": "test_user",
      "created_at": "2016-02-20T03:27:58.152Z",
      "updated_at": "2016-02-20T03:27:58.255Z"
    }
  ]
}

Báječné! Máme uživatele a ti mají zašifrovaná hesla.

Skrytí citlivých polí a ověření modelu

Navštivte http://localhost:3000/v1/users ve vašem prohlížeči zobrazíte seznam všech uživatelů - můžete zaznamenat problém. Rozhraní API vrátí zašifrované heslo. Tohle není něco, co chceme. Abychom to napravili, otevřeme app/models/user.js :

Najděte řádky:

User.validates('email', 'must be valid', v => v && (v + '').match(/.+@.+\.\w+/i));
User.validates('password', 'must be at least 5 characters in length', v => v && v.length >= 5);

Pod ně přidejte:

User.hides('password');

Otevřete http://localhost:3000/v1/users ve vašem prohlížeči a voila! Heslo zmizelo.

Možná se ptáte, co je to User.validates(...) hovory jsou o. No, zkusme nový curl žádost s heslem...

$ curl --data "username=test_user&[email protected]" http://localhost:3000/v1/users

Úžasný! Naše ověření fungují podle očekávání. Můžete si s nimi zkusit hrát sami.

{
  "meta": {
    "total": 0,
    "count": 0,
    "offset": 0,
    "error": {
      "message": "Validation error",
      "details": {
        "password": [
          "must be at least 5 characters in length"
        ]
      }
    }
  },
  "data": []
}

Připojování uživatelů k tweetům v odpovědích API

Všimnete si toho v našem prvním Tweet zadali jsme user_id . Můžeme se ujistit, že připojíme uživatele k tweetům v naší odpovědi API, když uděláme následující.

Nejprve otevřete app/models/tweet.js :

module.exports = (function() {

  'use strict';

  const Nodal = require('nodal');

  class Tweet extends Nodal.Model {}

  Tweet.setDatabase(Nodal.require('db/main.js'));
  Tweet.setSchema(Nodal.my.Schema.models.Tweet);

  return Tweet;

})();

Před return Tweet , přidejte řádky:

const User = Nodal.require('app/models/user.js');
Tweet.joinsTo(User, {multiple: true});

Nyní otevřete app/controllers/v1/tweets_controllers.js a najděte index() :

index() {

  Tweet.query()
    .where(this.params.query)
    .end((err, models) => {

      this.respond(err || models);

  });
}

Změňte toto na:

index() {

  Tweet.query()
    .where(this.params.query)
    .join('user')
    .end((err, models) => {
      this.respond(err || models, ['id', 'body', 'created_at', 'user']);
    });
}

Obnovit http://localhost:3000/v1/tweets ve vašem prohlížeči a měli byste vidět:

{
  "meta": {
    "total": 1,
    "count": 1,
    "offset": 0,
    "error": null
  },
  "data": [
    {
      "id": 1,
      "body": "Testing",
      "created_at": "2016-02-20T03:21:30.879Z",
      "user": {
        "id": 1,
        "email": "[email protected]",
        "username": "test_user",
        "created_at": "2016-02-20T03:27:58.152Z",
        "updated_at": "2016-02-20T03:27:58.255Z"
      }
    }
  ]
}

Možná jste si všimli, že jsme předali druhý parametr do this.respond(...) . Tento parametr je známý jako Rozhraní modelu a sděluje řadiči, která pole modelu má skutečně zobrazit v odpovědi API. Ve výchozím nastavení Controller zobrazí všechna pole s výjimkou těch, která jste označili jako necitlivá / skrytá (shora). Nebude zobrazte však všechny spojené modely. Budete je muset zadat ručně (jako jsme to udělali zde, s 'user' ). Pokud chcete omezit, která pole z User model show, proveďte následující:

this.respond(err || models, ['id', 'body', 'created_at', {user: ['username']}]);

Připojování tweetů k uživatelům

Připojování tweetů k uživatelům je podobný proces. Přidáme do app/models/user.js :

const Tweet = Nodal.require('app/models/tweet.js');
User.joinedBy(Tweet, {multiple: true});

Poznámka :Ujistěte se, že joinsTo by měl být vždy uveden nadítě tabulka (podle toho, která tabulka / model má parent_id pole) ajoinedBy je vždy uvedeno na nadřazeném stůl. Tyto konvence jsou důležité.

Podobně v app/controllers/v1/user_controller.js změňte index() způsob:

index() {

  User.query()
    .where(this.params.query)
    .join('tweets')
    .end((err, models) => {

      this.respond(
          err || models,
          [
            'id',
            'username',
            'email',
            'tweets'
          ]
        );
    });
}

a uvidíte odpověď:

{
  "meta": {
    "total": 1,
    "count": 1,
    "offset": 0,
    "error": null
  },
  "data": [
    {
      "id": 1,
      "username": "test_user",
      "email": "[email protected]",
      "tweets": [
        {
          "id": 1,
          "user_id": 1,
          "body": "Testing",
          "created_at": "2016-02-20T03:21:30.879Z",
          "updated_at": "2016-02-20T03:21:30.882Z"
        }
      ]
    }
  ]
}

Nasazení vaší databáze

Dobře, to je skvělé, ale pojďme vygenerovat testovací data!

Otevřete config/seed.json :

{
  "development": {},

  "test": {},

  "production": {}

}

Upravte to na:

{

  "development": {
    "User": [
      {
        "username": "Rihanna",
        "email": "[email protected]",
        "password": "password"
      },
      {
        "username": "The Weeknd",
        "email": "[email protected]",
        "password": "password"
      },
      {
        "username": "Drake",
        "email": "[email protected]",
        "password": "password"
      }
    ],
    "Tweet": [
      {
        "userid": 1,
        "body": "Hello, world"
      },
      {
        "userid": 2,
        "body": "hello, world!"
      },
      {
        "user_id": 3,
        "body": "You used to call me on my cell phone, world"
      }
    ]
  },

"test": {},

"production": {}

}

Nyní spustíme:

$ nodal db:bootstrap

A navštivte http://localhost:3000/v1/tweets (ujistěte se, že server běží):

{
  "meta": {
    "total": 3,
    "count": 3,
    "offset": 0,
    "error": null
  },
  "data": [
    {
      "id": 1,
      "body": "Hello, world",
      "created_at": "2016-02-20T04:08:38.762Z",
      "user": {
        "id": 1,
        "email": "[email protected]",
        "username": "Rihanna",
        "created_at": "2016-02-20T04:08:38.765Z",
        "updated_at": "2016-02-20T04:08:38.765Z"
      }
    },
    {
      "id": 2,
      "body": "hello, world!",
      "created_at": "2016-02-20T04:08:38.764Z",
      "user": {
        "id": 2,
        "email": "[email protected]",
        "username": "The Weeknd",
        "created_at": "2016-02-20T04:08:38.767Z",
        "updated_at": "2016-02-20T04:08:38.767Z"
      }
    },
    {
      "id": 3,
      "body": "You used to call me on my cell phone, world",
      "created_at": "2016-02-20T04:08:38.764Z",
      "user": {
        "id": 3,
        "email": "[email protected]",
        "username": "Drake",
        "created_at": "2016-02-20T04:08:38.767Z",
        "updated_at": "2016-02-20T04:08:38.767Z"
      }
    }
  ]
}

Úžasný! To, co jsme zde udělali, je nastavení počátečního bodu databáze zadáním pole hodnot, kterými naplníme každou tabulku v databázi. Klíč foreach pole (jako "User" ) je pouze název modelu. db:bootstrap je příkaz, který spouští nodal db:prepare , nodal db:migrate a nodal db:seed , v tomto pořadí.

Dotazování vašeho koncového bodu

Poslední věc, kterou uděláme, je, že se začneme ptát našeho koncového bodu na různé typy výsledků. Možná jste si všimli .where(this.params.query) na index() metoda pro oba naše ovladače. Tím se vytváří filtr pomocí kterého selektivně vybíráme, jaké výsledky chceme na základě parametrů dotazu HTTP.

Zkuste například otevřít tyto v prohlížeči:

http://localhost:3000/v1/tweets?body=Hello,%20world
http://localhost:3000/v1/tweets?body__is=Hello,%20world
http://localhost:3000/v1/tweets?body__not=Hello,%20world
http://localhost:3000/v1/tweets?body__startswith=Hello
http://localhost:3000/v1/tweets?body__istartswith=Hello
http://localhost:3000/v1/tweets?body__endswith=world
http://localhost:3000/v1/tweets?user__username=Drake

Komparátory podporované adaptérem PostgreSQL (vyžadováno __ před nimi) jsou:

is
not
lt
lte
gt
gte
contains
icontains
startswith
istartswith
endswith
iendswith
like
ilike
is_null
not_null
in
not_in
json
jsoncontains

Pamatujte, že výchozí nastavení je __is a můžete se dotazovat na spojené modely pomocí názvu spojení (tj. user ) a pole oddělte také dvojitým podtržením (__ ).

Užívejte si a objevujte dál!

Tím tutoriál prozatím končí. Nezapomeňte, že kompletní verzi všeho, co je zde nastíněno, najdete na keithwhor/instatweet-api. S Nodalem můžete dělat mnohem víc, včetně této ukázky GraphQL, ale mělo by zde být dostatek materiálu, abyste mohli začít.

Podívejte se na web Nodal a označte úložiště na GitHubu hvězdičkou, aby bylo aktuální, jak projekt roste a postupuje. Vítáme vás, abyste se připojili ke komunitě! Náš kanál Gitter je skvělým místem pro rychlé odpovědi a odkazy.

Kromě toho můžete sledovat spolu se sadou screencastů, které procházejí velmi podobným materiálem založeným na Nodal 0.6.

Děkuji za přečtení. :) Můžete mě sledovat na Twitteru na @keithwhor.