laravel api dearbhadh

Bidh frèam Laravel a’ sàbhaladh ùine do luchd-leasachaidh le bhith a’ taobhadh ri gnàthachadh mu rèiteachadh.

Tha Laravel ag amas air a thighinn air adhart leis an lìon, agus gu sgiobalta a’ toirt a-steach grunn fheartan agus bheachdan ùr-ghnàthach bho shaoghal leasachadh lìn.

Ciudha obrach, Dearbhadh API Laravel, conaltradh fìor-ùine agus mòran a bharrachd.

13 minuti

A bheil thu speisealaichte ann a bhith a’ leasachadh bathar-bog gus seirbheisean air-loidhne a sholarachadh? Uill, an uairsin tha mi a’ smaoineachadh gum bu chòir dhut beachdachadh air buileachadh APIs RESTful le frèam Laravel.

Le bhith a’ dèanamh seo, bidh e comasach dhut bathar-bog a dhèanamh le bhith ag amas air mion-sgrùdadh, còd glan, agus deuchainn a dhèanamh air a ghnìomhachd ann an dòigh shìmplidh agus iomlan.

Mar sin ma tha thu airson barrachd fhaighinn a-mach agus airson faighinn a-mach mar a chuireas tu fear an gnìomh APIs RESTful le Laravel, Tha mi a’ moladh gun toir thu beagan mhionaidean an-asgaidh dìreach dhut fhèin agus sa bhad tòisich a ’cuimseachadh air an stiùireadh seo dhòmhsa le fòcas air a’ chuspair. A bheil thu deiseil? Tha ? Glè mhath: stadamaid a bhith a’ bruidhinn agus rachamaid air adhart leis!

San oideachadh seo chì sinn mar a chruthaicheas tu agus a nì thu deuchainn air fear Laravel RESTful API agus an laravel api dearbhadh làidir a’ cleachdadh an fhrèam Laravel le dearbhadh.

laravel RESTful api

REST sta per Gluasad Stàite Riochdachail agus tha e na stoidhle ailtireachd airson conaltradh lìonra eadar tagraidhean, a tha stèidhichte air protocol gun stàite (mar as trice HTTP) airson eadar-obrachadh.

Tha gnìomhairean HTTP a’ riochdachadh ghnìomhan

Nelle API Laravel RESTful, bidh sinn a’ cleachdadh ghnìomhairean HTTP mar ghnìomhan agus an endpoint is iad sin na goireasan air am bi aon ag obair. Cleachdaidh sinn gnìomhairean HTTP airson an ciall semantach:

  • GET: goireasan fhaighinn air ais
  • POST: cruthaich goireasan
  • PUT: Ùraich na goireasan
  • DELETE: Sguab às goireasan
Tha modhan HTTP a’ riochdachadh na gnìomhan airson dearbhadh API Laravel
Tha modhan HTTP a’ riochdachadh ghnìomhan

Gnìomh Ùrachaidh: PUT vs. POST

A thaobh an API RESTful tha diofar bheachdan ann a thaobh am bu chòir ùrachadh le POSTPATCHno PUT, no a bheil e nas fheàrr an gnìomh fhàgail create ris a' ghnìomhair PUT. San artaigil seo cleachdaidh sinn PUT airson an gnìomh ùrachaidh, oir a rèir HTTP RFCPUT a’ ciallachadh goireas a chruthachadh/ùrachadh ann an àite sònraichte. Riatanas eile airson a’ ghnìomhair PUT tha iempotency, a tha sa chùis seo gu bunaiteach a’ ciallachadh gun urrainn dhut an t-iarrtas sin a chuir 1, 2, no 1000 uair agus bidh an toradh mar an ceudna: goireas ùraichte ann an stòr-dàta.

goireas laravel api

Bidh na goireasan mar amasan nan gnìomhan, nar cùise Items e Users, agus bithidh an cuid fèin aca aig an deireadh:

  • /nithean
  • /luchd-cleachdaidh

Anns an oideachadh seo air goireas laravel api, bidh riochdachadh 1: 1 aig maoin anns na modalan dàta againn. Tha e comasach goireasan a bhith air an riochdachadh ann am barrachd air aon mhodail dàta (no chan eil idir stòr-dàta) agus modailean a tha gu tur nach eil ruigsinneach don neach-cleachdaidh. Aig a’ cheann thall, bidh thu a’ co-dhùnadh ciamar a dhealbhaicheas tu maoin agus teamplaidean a fhreagras air an tagradh agad.

Nota air cunbhalachd

Is e am buannachd as motha a bhith a 'cleachdadh seata de ghnàthasan mar REST an e sin leatsa API bidh e tòrr nas fhasa a chleachdadh agus a leasachadh. cuid endpoint tha iad gu math sìmplidh agus, mar sin, do API bidh e tòrr nas fhasa a chleachdadh agus a riaghladh na endpoint tighinn GET /get_item?id_item=12 POST /delete_item?number=40.

Ach, ann an cuid de chùisean bidh e duilich mapadh gu pàtran cruthaich/fhaighinn air ais/ùrachadh/cuir às. Cuimhnich nach fheum gnìomhairean a bhith ann an URLan agus nach fheum goireasan a bhith nan sreathan ann an clàr. Is e rud eile ri chumail nad inntinn nach fheum thu a h-uile gnìomh a chuir an gnìomh airson a h-uile goireas.

Suidheachadh pròiseict airson seirbheis lìn Laravel

Coltach ris a h-uile frèam PHP ùr-nodha, bidh feum againn le Sgrìobhadair gus ar eisimeileachd a stàladh agus a riaghladh. Às deidh dhuinn an stiùireadh luchdaich sìos a leantainn (agus an caochladair àrainneachd a chuir ris an t-slighe), leig dhuinn a stàladh Laravel a 'cleachdadh an òrdugh:

$ composer global require laravel/installer

Às deidh an stàladh a bhith deiseil, faodaidh tu tagradh ùr a chruthachadh mar a leanas:

$ laravel new myapp

Airson an àithne gu h-àrd, feumaidh tu a bhith ~/composer/vendor/bin anns an fhaidhle agad $PATH. Mura h-eil thu airson dèiligeadh ri sin, faodaidh tu cuideachd pròiseact ùr a chruthachadh a’ cleachdadh Composer, mar a leanas:

$ composer create-project --prefer-dist laravel/laravel myapp

Con Laravel stàlaichte, bu chòir dhut a bhith comasach air an fhrithealaiche a thòiseachadh agus dèanamh cinnteach a bheil a h-uile càil ag obair:

$ php artisan serve
Laravel development server started: <http://127.0.0.1:8000>
Laravel am frithealaiche
Laravel air a stàladh

Nuair a dh'fhosglas tu 

https://localhost:8000 sa bhrobhsair agad, bu chòir dhut an duilleag eisimpleir seo fhaicinn.

Imrich agus Modailean

Mus sgrìobh sinn ar cuid migration, feumaidh sinn dèanamh cinnteach gu bheil a stòr-dàta chruthachadh airson an aplacaid seo agus cuir a theisteasan ris an fhaidhle .env suidhichte aig bonn a’ phròiseict.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=warehoue
DB_USERNAME=warehoue
DB_PASSWORD=topsecret

Feuch an tòisich sinn leis a’ chiad fhear againn model e migration: anitem, a bu chòir raon ainm agus raon prìsean a bhith aca, a bharrachd air ceann-latha cruthachaidh. Laravel a’ toirt seachad grunn òrdughan tro Artisan, a chuidicheas sinn gus faidhlichean a ghineadh le bhith gan cur anns na pasganan ceart. Gus am modail a chruthachadh Item, is urrainn dhuinn ruith:

$ php artisan make:model Item -m

An roghainn -m tha goirid airson --migration agus a' comharrachadh ad Artisan gus fear a chruthachadh airson ar modail. Seo an imrich a chaidh a chruthachadh:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateItemsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('items', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('items');
    }
}

Nach bris sinn sìos e airson diog:

  • Na dòighean-obrach up()down() air an coileanadh fa leth rè an migrate agus gin rollback;
  • $table->increments('id') a’ suidheachadh raon iomlanachd fèin-àrdachaidh le bhith ga ainmeachadh id;
  • $table->timestamps() suidhichidh e na raointean created_atupdated_at de sheòrsa timestamp. Chan fheum sinn a bhith draghail mu bhith a’ suidheachadh luach bunaiteach, oir Laravel a’ gabhail cùram de bhith ag ùrachadh nan raointean sin nuair a bhios feum air.
  • Agus mu dheireadh, Schema::dropIfExists() an clàr a sguabadh às, ma tha e ann.

Le sin air a ràdh, cuiridh sinn dà loidhne ris an dòigh-obrach againn up():

public function up()
{
    Schema::create('items', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->double('price');
        $table->timestamps();
    });
}

An dòigh-obrach string() bidh e a’ cruthachadh colbh dhuinn VARCHAR co-ionann fhad 'sa tha an dòigh-obrach double() a' cruthachadh dhuinn a DOUBLE co-ionann. Aon uair ‘s gu bheil seo air a dhèanamh, rachamaid air adhart leis an imrich:

$ php artisan migrate

Faodaidh tu cuideachd an roghainn a chleachdadh --step, a bhios a’ sgaradh gach imrich a-steach don bhaidse aige fhèin gus an urrainn dhut an toirt air ais leotha fhèin ma tha sin riatanach.

Laravel a’ tighinn le dà imrich create_users_table create_password_resets_table. Cha chleachd sinn am bòrd password_resets, ach am bòrd users bidh e feumail dhuinn.

A-nis rachamaid air ais chun mhodail againn agus cuir na buadhan sin ris an raon $fillable gus an urrainn dhut an cleachdadh anns na teamplaidean agad Item::create e Item::update

class Item extends Model
{
    protected $fillable = ['name', 'price'];
}

Na raointean taobh a-staigh an togalaich $fillable faodar a shònrachadh gu mòr a’ cleachdadh dhòighean create() e update() di Eloquent. Faodaidh tu cuideachd an togalach a chleachdadh $guarded gus a h-uile seilbh a cheadachadh ach cuid.

Stòr-dàta sìolachaidh

Il a ’sìolachadh den stòr-dàta 's e pròiseas a' lìonadh an stòr-dàta le dàta meallta as urrainn dhuinn a chleachdadh airson a dhearbhadh. Laravel a' tighinn leis faker , leabharlann sgoinneil airson dìreach an cruth ceart de dhàta meallta a ghineadh dhuinn. Mar sin cruthaichidh sinn a’ chiad fhear againn seeder:

$ php artisan make:seeder ItemsTableSeeder

I seeders tha iad anns an eòlaire /database/seeds. Seo cò ris a bhios e coltach às deidh dhut a chuir air dòigh gus cuid a chruthachadh items:

class ItemsTableSeeder extends Seeder
{
    public function run()
    {
        // Let's truncate our existing records to start from scratch.
        Item::truncate();

        $faker = \Faker\Factory::create();

        // And now, let's create a few items in our database:
        for ($i = 0; $i < 50; $i++) {
            Item::create([
                'name' => $faker->sentence,
                'price' => $book->setPrice($faker->randomNumber(2)),
            ]);
        }
    }
}

An uairsin bidh sinn a 'ruith an àithne seed:

$ php artisan db:seed --class=ItemTableSeeder

Bidh sinn ag ath-aithris a’ phròiseas airson cruthachadh a seeder Users:

class UsersTableSeeder extends Seeder
{
    public function run()
    {
        // Let's clear the users table first
        User::truncate();

        $faker = \Faker\Factory::create();

        // Let's make sure everyone has the same password and 
        // let's hash it before the loop, or else our seeder 
        // will be too slow.
        $password = Hash::make('bloginnovazione');

        User::create([
            'name' => 'Administrator',
            'email' => 'admin@test.com',
            'password' => $password,
        ]);

        // And now let's generate a few dozen users for our app:
        for ($i = 0; $i < 10; $i++) {
            User::create([
                'name' => $faker->name,
                'email' => $faker->email,
                'password' => $password,
            ]);
        }
    }
}

Is urrainn dhuinn a dhèanamh nas fhasa le bhith a’ cur ar cuid fhèin ris sìol alla Stòr-dàta Seeder Class prìomh taobh a-staigh an stòr-dàta/ sìol pasgan:

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        $this->call(ItemsTableSeeder::class);
        $this->call(UsersTableSeeder::class);
    }
}

San dòigh seo, is urrainn dhuinn dìreach a chuir an gnìomh $php artisan db:seed agus cuirear gu bàs gach clas ris an abrar am modh run().

Slighean agus luchd-riaghlaidh

Bidh sinn gan cruthachadh endpoint bunaiteach airson an tagraidh againn: cruthaich, faigh liosta, faigh liosta shingilte, ùraich agus cuir às. Air an fhaidhle routes/api.php, is urrainn dhuinn dìreach seo a dhèanamh:

Use App\Item;
 
Route::get('items', function() {
    // If the Content-Type and Accept headers are set to 'application/json', 
    // this will return a JSON structure. This will be cleaned up later.
    return Item::all();
});
 
Route::get('items/{id}', function($id) {
    return Items::find($id);
});

Route::post('items', function(Request $request) {
    return Item::create($request->all);
});

Route::put('items/{id}', function(Request $request, $id) {
    $item = Item::findOrFail($id);
    $item->update($request->all());

    return $item;
});

Route::delete('items/{id}', function($id) {
    Item::find($id)->delete();

    return 204;
})

Na slighean a-staigh api.php bidh an ro-leasachan aca /api/ agus an middleware Thèid cuingealachadh API a chuir an sàs gu fèin-ghluasadach air na slighean sin (ma tha thu airson an ro-leasachan a thoirt air falbh faodaidh tu an clas a dheasachadh RouteServiceProvider su /app/Providers/RouteServiceProvider.php).

A-nis gluaisidh sinn an còd seo gu a chòd fhèin Controller:

$ php artisan make:controller ItemController

ItemController.php:

use App\Item;
 
class ItemController extends Controller
{
    public function index()
    {
        return Item::all();
    }
 
    public function show($id)
    {
        return Item::find($id);
    }

    public function store(Request $request)
    {
        return Item::create($request->all());
    }

    public function update(Request $request, $id)
    {
        $item = Item::findOrFail($id);
        $item->update($request->all());

        return $item;
    }

    public function delete(Request $request, $id)
    {
        $item = Item::findOrFail($id);
        $item->delete();

        return 204;
    }
}

Am faidhle routes/api.php:

Route::get('items', 'ItemController@index');
Route::get('items/{id}', 'ItemController@show');
Route::post('items', 'ItemController@store');
Route::put('items/{id}', 'ItemController@update');
Route::delete('items/{id}', 'ItemController@delete');

Is urrainn dhuinn an leasachadh endpoint cleachdadh ceangal modail slighe so-thuigsinn. San dòigh seo, Laravel bheir e a-steach an eisimpleir Item anns na dòighean againn agus tillidh sinn 404 gu fèin-ghluasadach mura lorgar e. Feumaidh sinn atharraichean a dhèanamh air faidhle nan slighean agus an rianadair:

Route::get('items', 'ItemController@index');
Route::get('items/{item}', 'ItemController@show');
Route::post('items', 'ItemController@store');
Route::put('items/{item}', 'ItemController@update');
Route::delete('items/{item}', 'ItemController@delete');
class ItemController extends Controller
{
    public function index()
    {
        return Item::all();
    }

    public function show(Item $item)
    {
        return $item;
    }

    public function store(Request $request)
    {
        $item= Item::create($request->all());

        return response()->json($item, 201);
    }

    public function update(Request $request, Item $item)
    {
        $item->update($request->all());

        return response()->json($item, 200);
    }

    public function delete(Item $item)
    {
        $item->delete();

        return response()->json(null, 204);
    }
}

Còdan inbhe HTTP agus cruth freagairt

Cuiridh sinn an response()->json() ai endpoint. Leigidh seo leinn dàta a thilleadh gu soilleir JSON agus cuir còd HTTP a dh'fhaodas an neach-dèiligidh a pharsadh. Is iad na còdan as cumanta a thilleas tu:

  • 200: Ceart gu leòr. An còd soirbheachais àbhaisteach agus an roghainn bunaiteach.
  • 201: nì air a chruthachadh. Feumail airson storegnìomhan.
  • 204: Gun susbaint. Nuair a chaidh gnìomh a choileanadh gu soirbheachail, ach chan eil susbaint ri thilleadh.
  • 206: Susbaint pàirt. Feumail nuair a dh'fheumas tu liosta de ghoireasan le duilleagan a thilleadh.
  • 400: Droch iarrtas. An roghainn àbhaisteach airson iarrtasan nach eil air an dearbhadh.
  • 401: Chan eil ceadaichte. Feumaidh an cleachdaiche a bhith air a dhearbhadh.
  • 403: Toirmisgte. Tha an cleachdaiche dearbhte, ach chan eil cead aige gnìomh a dhèanamh.
  • 404: Gun a lorg. Thèid seo a thilleadh gu fèin-ghluasadach le Laravel nuair nach lorgar an goireas.
  • 500: Mearachd frithealaiche a-staigh. Is fheàrr nach till thu gu soilleir e, ach ma bhriseas rudeigin ris nach robh dùil, is e seo a gheibh an neach-cleachdaidh agad.
  • 503: Seirbheis nach eil ri fhaighinn. Gu math fèin-mhìneachail, ach cuideachd còd eile nach tèid a thilleadh gu soilleir leis an tagradh.

A’ cur freagairt ceart 404

Ma dh’ fheuch thu ri goireas nach robh ann fhaighinn, thèid eisgeachd a thilgeil ort agus gheibh thu an stac air fad, mar seo:

NotFoundHttpException Stacktrace

Is urrainn dhuinn an duilgheadas seo fhuasgladh le bhith ag atharrachadh ar clas làimhseachadh eisgeachd, suidhichte aig app/Exceptions/Handler.php, gus freagairt a thilleadh JSON:

public function render($request, Exception $exception)
{
    // This will replace our 404 response with
    // a JSON response.
    if ($exception instanceof ModelNotFoundException) {
        return response()->json([
            'error' => 'Resource not found'
        ], 404);
    }

    return parent::render($request, $exception);
}

Seo eisimpleir den tilleadh:

{
    data: "Resource not found"
}

Ma tha thu a 'cleachdadh Laravel gus duilleagan eile a fhrithealadh, feumaidh tu an còd atharrachadh gus toirt air obrachadh leis a’ bhann-cinn Accept, air neo tillidh 404 mearachd bho iarrtasan cunbhalach a JSON.

public function render($request, Exception $exception)
{
    // This will replace our 404 response with
    // a JSON response.
    if ($exception instanceof ModelNotFoundException &&
        $request->wantsJson())
    {
        return response()->json([
            'data' => 'Resource not found'
        ], 404);
    }

    return parent::render($request, $exception);
}

Anns a 'chùis seo, bidh feum aig iarrtasan API air a' cheann-cinn Accept: application/json.

laravel api dearbhadh

Tha iomadh dòigh ann airson a chur an gnìomh laravel api dearbhadh (tha fear dhiubh Cead-siubhail , deagh dhòigh air OAuth2 a bhuileachadh), ach san artaigil seo gabhaidh sinn dòigh-obrach gu math nas sìmplidhe.

Gus tòiseachadh, feumaidh sinn raon a chuir ris api_token chun a' bhùird users:

$ php artisan make:migration --table=users adds_api_token_to_users_table

Agus an uairsin cuir an gnìomh an imrich:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->string('api_token', 60)->unique()->nullable();
    });
}

public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->dropColumn(['api_token']);
    });
}

Às deidh sin, dìreach imrich leis an àithne ceàirde:

$ php artisan migrate

A 'cruthachadh crìoch a' chlàraidh

A chur an gnìomh a laravel api dearbhadh cleachdaidh sinn an samhla RegisterController (sa phasgan Auth) am freagairt ceart a thilleadh nuair a chlàraicheas tu. Laravel Tha e a’ tighinn le dearbhadh a-mach às a’ bhogsa, ach feumaidh sinn fhathast a thweaked beagan gus am freagairt a tha sinn ag iarraidh a thilleadh.

Bidh an rianadair dàta a’ cleachdadh am feart gu RegistersUsers cuir an gnìomh logadh. Seo mar a tha e ag obair:

public function register(Request $request)
{
    // Here the request is validated. The validator method is located
    // inside the RegisterController, and makes sure the name, email
    // password and password_confirmation fields are required.
    $this->validator($request->all())->validate();

    // A Registered event is created and will trigger any relevant
    // observers, such as sending a confirmation email or any 
    // code that needs to be run as soon as the user is created.
    event(new Registered($user = $this->create($request->all())));

    // After the user is created, he's logged in.
    $this->guard()->login($user);

    // And finally this is the hook that we want. If there is no
    // registered() method or it returns null, redirect him to
    // some other URL. In our case, we just need to implement
    // that method to return the correct response.
    return $this->registered($request, $user)
                    ?: redirect($this->redirectPath());
}

Feumaidh sinn dìreach an dòigh-obrach a chuir an gnìomh registered() anns an fhaidhle againn RegisterController. Tha an dòigh-obrach a 'faighinn an $request e $user, agus sin a tha sinn ag iarraidh. Seo cò ris a bu chòir an dòigh a bhith coltach taobh a-staigh an rianadair:

protected function registered(Request $request, $user)
{
    $user->generateToken();

    return response()->json(['data' => $user->toArray()], 201);
}

Agus is urrainn dhuinn a cheangal ris an fhaidhle slighean:

Route::post('register', 'Auth\RegisterController@register');

Anns an earrainn roimhe, chleachd sinn modh air a 'mhodail User gus an token. Tha seo feumail gus nach eil againn ach aon dòigh air i token. Cuir an dòigh a leanas ris a’ mhodal cleachdaiche agad:

class User extends Authenticatable
{
    ...
    public function generateToken()
    {
        $this->api_token = str_random(60);
        $this->save();

        return $this->api_token;
    }
}

Tha an neach-cleachdaidh a-nis clàraichte agus taing dha dearbhadh Laravel agus dearbhadh sa bhad, na raointean nameemailpassword password_confirmation tha iad èigneachail agus thèid fios air ais a làimhseachadh gu fèin-ghluasadach. Thoir sùil air an dòigh-obrach validator() a-staigh de RegisterController gus faicinn mar a tha na riaghailtean air an cur an gnìomh.

Seo na gheibh sinn nuair a ruigeas sinn anendpoint:

$ curl -X POST http://localhost:8000/api/register \
 -H "Accept: application/json" \
 -H "Content-Type: application/json" \
 -d '{"name": "John", "email": "john.doe@bloginnovazione.it", "password": "bloginnovazione123", "password_confirmation": "bloginnovazione123"}'
{
    "data": {
        "api_token":"0syHnl0Y9jOIfszq11EC2CBQwCfObmvscrZYo5o2ilZPnohvndH797nDNyAT",
        "created_at": "2017-06-20 21:17:15",
        "email": "john.doe@bloginnovazione.it",
        "id": 51,
        "name": "John",
        "updated_at": "2017-06-20 21:17:15"
    }
}

A’ cruthachadh puing crìochnachaidh logadh a-steach

Dìreach mar anendpoint clàradh, is urrainn dhuinn atharrachadh LoginController (sa phasgan Auth) gus taic a thoirt don dearbhadh API againn. An dòigh-obrach login di AuthenticatesUsers faodar a chuir thairis gus taic a thoirt don fheadhainn againn laravel api dearbhadh:

public function login(Request $request)
{
    $this->validateLogin($request);

    if ($this->attemptLogin($request)) {
        $user = $this->guard()->user();
        $user->generateToken();

        return response()->json([
            'data' => $user->toArray(),
        ]);
    }

    return $this->sendFailedLoginResponse($request);
}

Agus is urrainn dhuinn a cheangal ris an fhaidhle slighean:

Route::post('login', 'Auth\LoginController@login');

A-nis, a 'gabhail ris gu bheil i seeders air an cur gu bàs, is e seo a gheibh sinn nuair a chuireas sinn iarrtas thugainn POST chun na slighe sin:

$ curl -X POST localhost:8000/api/login \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -d "{\"email\": \"admin@test.com\", \"password\": \"bloginnovazione\" }"
{
    "data": {
        "id":1,
        "name":"Administrator",
        "email":"admin@test.com",
        "created_at":"2017-04-25 01:05:34",
        "updated_at":"2017-04-25 02:50:40",
        "api_token":"Jll7q0BSijLOrzaOSm5Dr5hW9cJRZAJKOzvDlxjKCXepwAeZ7JR6YP5zQqnw"
    }
}

Gus an token ann an iarrtas, faodaidh tu seo a dhèanamh le bhith a’ cur feart api_token Nel payload no ciamar token neach-giùlain anns na cinn-cinn iarrtais ann an cruth Authorization: Bearer Jll7q0BSijLOrzaOSm5Dr5hW9cJRZAJKOzvDlxjKCXepwAeZ7JR6YP5zQqnw.

Dì-cheangal

Leis an ro-innleachd làithreach againn, ma tha an comharra ceàrr no a dhìth, bu chòir don neach-cleachdaidh freagairt gun dearbhadh fhaighinn (a chuireas sinn an gnìomh san ath earrann). Mar sin, airson a endpoint de dhì-cheangal sìmplidh, cuiridh sinn an token agus bheirear air falbh e stòr-dàta.

routes/api.php:

Route::post('logout', 'Auth\LoginController@logout');

Auth\LoginController.php:

public function logout(Request $request)
{
    $user = Auth::guard('api')->user();

    if ($user) {
        $user->api_token = null;
        $user->save();
    }

    return response()->json(['data' => 'User logged out.'], 200);
}

A’ cleachdadh na ro-innleachd seo, bidh ge bith dè an tòcan a th’ aig an neach-cleachdaidh neo-dhligheach agus an API Laravel diùltadh ruigsinneachd (a’ cleachdadh middleware, mar a tha air a mhìneachadh san ath earrann). Feumaidh seo a bhith air a cho-òrdanachadh leis a’ cheann-aghaidh gus nach bi an neach-cleachdaidh fhathast air logadh a-steach gun cothrom fhaighinn air susbaint sam bith.

A’ cleachdadh bathar-meadhain gus ruigsinneachd a chuingealachadh

Aon uair 's gu bheil e air a chruthachadh api_token, is urrainn dhuinn am faidhle a chuir an gnìomh / a chuir dheth middleware dearbhadh anns an fhaidhle slighean:

Route::middleware('auth:api')
    ->get('/user', function (Request $request) {
        return $request->user();
    });

Gheibh sinn cothrom air a’ chleachdaiche gnàthach a’ cleachdadh an dòigh $request->user() no tron facade Auth

Auth::guard('api')->user(); // instance of the logged user
Auth::guard('api')->check(); // if a user is authenticated
Auth::guard('api')->id(); // the id of the authenticated user

Agus gheibh sinn toradh mar seo:

Argument Mì-dhligheach StacktraceException

Tha seo air sgàth gu feum sinn an dòigh-obrach atharrachadh unauthenticated an-dràsta sa chlas againn Handler. Tha an tionndadh làithreach a' tilleadh a JSON dìreach ma tha ceann-cinn air an iarrtas Accept: application/json, mar sin atharraichidh sinn e:

protected function unauthenticated($request, AuthenticationException $exception)
{
    return response()->json(['error' => 'Unauthenticated'], 401);
}

Aon uair ‘s gu bheil an duilgheadas seo air a rèiteachadh, is urrainn dhuinn a dhol air ais chun làrach endpoint den artaigil gus an cuir a-steach don bhathar-meadhanach auth:api. Faodaidh sinn seo a dhèanamh a’ cleachdadh buidhnean slighe:

Route::group(['middleware' => 'auth:api'], function() {
    Route::get('items', 'ItemController@index');
    Route::get('items/{item}', 'ItemController@show');
    Route::post('items', 'ItemController@store');
    Route::put('items/{item}', 'ItemController@update');
    Route::delete('items/{item}', 'ItemController@delete');
});

San dòigh seo chan fheum sinn am faidhle a shuidheachadh middleware airson gach slighe. Cha bhith e a’ sàbhaladh mòran ùine an-dràsta, ach mar a bhios am pròiseact a’ fàs bidh e na chuideachadh gus na slighean a chumail soilleir.

Dèan deuchainn air na puingean crìochnachaidh againn

Laravel gabhail a-steach amalachadh le PHPUnit deiseil airson a chleachdadh le faidhle phpunit.xml air a rèiteachadh mu thràth. Tha an framework tha e cuideachd a’ toirt dhuinn grunn chuideachadh agus dearbhaidhean a bharrachd a nì ar beatha gu math nas fhasa, gu sònraichte airson deuchainn laravel api dearbhadh.

Tha grunn innealan taobh a-muigh ann as urrainn dhut a chleachdadh gus do chuid fhèin a dhearbhadh API Laravel; ge-tà, deuchainn taobh a-staigh Laravel na roghainn eile nas fheàrr: faodaidh na buannachdan uile a bhith againn bho bhith a’ dèanamh deuchainn air structar agus toraidheanAPI cumail smachd iomlan air an stòr-dàta. Airson anendpoint den liosta, mar eisimpleir, b’ urrainn dhuinn factaraidh no dhà a ruith agus a ràdh gu bheil na goireasan sin anns an fhreagairt.

Airson tòiseachadh, feumaidh sinn cuid de na roghainnean atharrachadh gus a stòr-dàta SQLite mar chuimhneachan. Le bhith ga chleachdadh nì na deuchainnean againn gu math luath, ach is e a’ mhalairt-malairt nach obraich cuid de dh’ òrdughan imrich (cuingealachaidhean, mar eisimpleir) gu ceart san rèiteachadh shònraichte sin.

Bidh sinn cuideachd a’ ruith imrich ro gach deuchainn. Leigidh an rèiteachadh seo leinn am faidhle a thogail stòr-dàta airson gach deuchainn agus an uairsin sgrios e, a 'seachnadh seòrsa sam bith de eisimeileachd eadar deuchainnean.

Anns an fhaidhle againn config/database.php, feumaidh sinn an raon a shuidheachadh database, anns an rèiteachadh sqliteLe :memory::

...
'connections' => [

    'sqlite' => [
        'driver' => 'sqlite',
        'database' => ':memory:',
        'prefix' => '',
    ],
    
    ...
]

Mar sin leig leinn comas a thoirt SQLite in phpunit.xml, a’ cur caochladair na h-àrainneachd ris DB_CONNECTION:

    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="QUEUE_DRIVER" value="sync"/>
        <env name="DB_CONNECTION" value="sqlite"/>
    </php>

Le sin air a ràdh, chan eil air fhàgail ach ar clas a stèidheachadh TestCase bunait airson cleachdadh na migration agus seeder, roimh gach deuchainn. Gus seo a dhèanamh, feumaidh sinn a chur ris DatabaseMigrations agus an uairsin cuir fòn ris Artisan ris an dòigh-obrach againn setUp().

Seo an clas às deidh na h-atharrachaidhean:

use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Support\Facades\Artisan;

abstract class TestCase extends BaseTestCase
{
    use CreatesApplication, DatabaseMigrations;

    public function setUp()
    {
        parent::setUp();
        Artisan::call('db:seed');
    }
}

Is e aon rud ri chur ris an deuchainn òrdugh composer.json:

    "scripts": {
        "test" : [
            "vendor/bin/phpunit"
        ],
    ... 
    },    

Bidh an òrdugh deuchainn ri fhaighinn mar seo:

$ composer test

A 'suidheachadh an Factories airson deuchainn

Le factories leigidh iad leinn stuthan a chruthachadh gu sgiobalta leis an dàta cheart airson deuchainn. Tha iad suidhichte anns a 'phasgan database/factories. Laravel tha aon factory airson a’ chlas User, mar sin leig dhuinn fear a chuir ris airson a’ chlas Item:

$factory->define(App\Item::class, function (Faker\Generator $faker) {
    return [
        'title' => $faker->sentence,
        'body' => $faker->paragraph,
    ];
});

An stòr leabhraichean faker air a chuir a-steach mu thràth gus ar cuideachadh le bhith a’ cruthachadh an cruth dàta air thuaiream ceart airson ar modalan.

Na ciad deuchainnean againn

Faodaidh sinn na dòighean dearbhte a chleachdadh airson Laravel gus crìoch a ruighinn gu furasta agus a fhreagairt a mheasadh. Cruthaichidh sinn a’ chiad deuchainn againn, an deuchainn logadh a-steach, a’ cleachdadh an àithne a leanas:

$ php artisan make:test Feature/LoginTest

Agus seo an deuchainn againn:

class LoginTest extends TestCase
{
    public function testRequiresEmailAndLogin()
    {
        $this->json('POST', 'api/login')
            ->assertStatus(422)
            ->assertJson([
                'email' => ['The email field is required.'],
                'password' => ['The password field is required.'],
            ]);
    }


    public function testUserLoginsSuccessfully()
    {
        $user = factory(User::class)->create([
            'email' => 'testlogin@user.com',
            'password' => bcrypt('bloginnovazione123'),
        ]);

        $payload = ['email' => 'testlogin@user.com', 'password' => 'bloginnovazione123'];

        $this->json('POST', 'api/login', $payload)
            ->assertStatus(200)
            ->assertJsonStructure([
                'data' => [
                    'id',
                    'name',
                    'email',
                    'created_at',
                    'updated_at',
                    'api_token',
                ],
            ]);

    }
}

Bidh na modhan sin a 'dèanamh deuchainn air cùis no dhà sìmplidh. An dòigh-obrach json() a’ ruighinn a’ phuing crìochnachaidh agus tha na dearbhaidhean eile gu math fèin-mhìneachail. Mion-fhiosrachadh mu dheidhinn assertJson(): Bidh an dòigh seo ag atharrachadh an fhreagairt gu raon a bhios a’ lorg na h-argamaid, agus mar sin tha an òrdugh cudromach. Anns a 'chùis seo, faodaidh tu grunn ghlaisean a cheangal.

A-nis cruthaichidh sinn an deuchainn crìochnachaidh clàraidh agus sgrìobh sinn paidhir airson a’ phuing crìochnachaidh sin:

$ php artisan make:test RegisterTest

class RegisterTest extends TestCase
{
    public function testsRegistersSuccessfully()
    {
        $payload = [
            'name' => 'John',
            'email' => 'john@bloginnovazione.it',
            'password' => 'bloginnovazione123',
            'password_confirmation' => 'bloginnovazione123',
        ];

        $this->json('post', '/api/register', $payload)
            ->assertStatus(201)
            ->assertJsonStructure([
                'data' => [
                    'id',
                    'name',
                    'email',
                    'created_at',
                    'updated_at',
                    'api_token',
                ],
            ]);;
    }

    public function testsRequiresPasswordEmailAndName()
    {
        $this->json('post', '/api/register')
            ->assertStatus(422)
            ->assertJson([
                'name' => ['The name field is required.'],
                'email' => ['The email field is required.'],
                'password' => ['The password field is required.'],
            ]);
    }

    public function testsRequirePasswordConfirmation()
    {
        $payload = [
            'name' => 'John',
            'email' => 'john@bloginnovazione.it',
            'password' => 'bloginnovazione123',
        ];

        $this->json('post', '/api/register', $payload)
            ->assertStatus(422)
            ->assertJson([
                'password' => ['The password confirmation does not match.'],
            ]);
    }
}

Agus mu dheireadh, puing crìochnachaidh an logadh a-mach:

$ php artisan make:test LogoutTest
class LogoutTest extends TestCase
{
    public function testUserIsLoggedOutProperly()
    {
        $user = factory(User::class)->create(['email' => 'user@test.com']);
        $token = $user->generateToken();
        $headers = ['Authorization' => "Bearer $token"];

        $this->json('get', '/api/items', [], $headers)->assertStatus(200);
        $this->json('post', '/api/logout', [], $headers)->assertStatus(200);

        $user = User::find($user->id);

        $this->assertEquals(null, $user->api_token);
    }

    public function testUserWithNullToken()
    {
        // Simulating login
        $user = factory(User::class)->create(['email' => 'user@test.com']);
        $token = $user->generateToken();
        $headers = ['Authorization' => "Bearer $token"];

        // Simulating logout
        $user->api_token = null;
        $user->save();

        $this->json('get', '/api/items', [], $headers)->assertStatus(401);
    }
}

Tha e cudromach cuimhneachadh, rè deuchainn, nach eil an tagradh Laravel air ath-thòiseachadh air iarrtas ùr. Tha seo a’ ciallachadh, nuair a ruigeas sinn am bathar meadhanach dearbhaidh, gun sàbhail e an neach-cleachdaidh gnàthach san t-suidheachadh TokenGuardgus nach bualadh thu a-rithist stòr-dàta. Roghainn glic, ge-tà: anns a 'chùis seo tha e a' ciallachadh gum feum sinn an deuchainn suaicheantas a roinn ann an dà, gus duilgheadasan sam bith leis an neach-cleachdaidh a chaidh a thasgadh roimhe a sheachnadh.

Tha e sìmplidh cuideachd puingean crìochnachaidh nithean a dhearbhadh:

class ItemTest extends TestCase
{
    public function testsItemsAreCreatedCorrectly()
    {
        $user = factory(User::class)->create();
        $token = $user->generateToken();
        $headers = ['Authorization' => "Bearer $token"];
        $payload = [
            'title' => 'Lorem',
            'body' => 'Ipsum',
        ];

        $this->json('POST', '/api/items', $payload, $headers)
            ->assertStatus(200)
            ->assertJson(['id' => 1, 'title' => 'Lorem', 'body' => 'Ipsum']);
    }

    public function testsItemsAreUpdatedCorrectly()
    {
        $user = factory(User::class)->create();
        $token = $user->generateToken();
        $headers = ['Authorization' => "Bearer $token"];
        $item = factory(Item::class)->create([
            'title' => 'First Item',
            'body' => 'First Body',
        ]);

        $payload = [
            'title' => 'Lorem',
            'body' => 'Ipsum',
        ];

        $response = $this->json('PUT', '/api/items/' . $item->id, $payload, $headers)
            ->assertStatus(200)
            ->assertJson([ 
                'id' => 1, 
                'title' => 'Lorem', 
                'body' => 'Ipsum' 
            ]);
    }

    public function testsArtilcesAreDeletedCorrectly()
    {
        $user = factory(User::class)->create();
        $token = $user->generateToken();
        $headers = ['Authorization' => "Bearer $token"];
        $item = factory(Item::class)->create([
            'title' => 'First Item',
            'body' => 'First Body',
        ]);

        $this->json('DELETE', '/api/items/' . $item->id, [], $headers)
            ->assertStatus(204);
    }

    public function testItemsAreListedCorrectly()
    {
        factory(Item::class)->create([
            'title' => 'First Item',
            'body' => 'First Body'
        ]);

        factory(Item::class)->create([
            'title' => 'Second Item',
            'body' => 'Second Body'
        ]);

        $user = factory(User::class)->create();
        $token = $user->generateToken();
        $headers = ['Authorization' => "Bearer $token"];

        $response = $this->json('GET', '/api/items', [], $headers)
            ->assertStatus(200)
            ->assertJson([
                [ 'title' => 'First Item', 'body' => 'First Body' ],
                [ 'title' => 'Second Item', 'body' => 'Second Body' ]
            ])
            ->assertJsonStructure([
                '*' => ['id', 'body', 'title', 'created_at', 'updated_at'],
            ]);
    }

}

Autore