This sponsored post features a product relevant to our readers while meeting our editorial guidelines for being objective and educational.
Indonesian (Bahasa Indonesia) translation by Dika Budiaji (you can also view the original English article)
Dalam tutorial ini, kita akan membuat sebuah aplikasi kencan untuk iOS mirip dengan Tinder. Untuk suara dan pesan, kita akan memanfaatkan Sinch platform, memanfaatkan SDK yang kuat.
Dalam bagian pertama, kami akan berfokus pada pengembangan RESTful API untuk menyimpan dan mengambil informasi pengguna. Dalam bagian kedua, iOS klien akan menghubungkan ke API ini untuk menemukan pengguna terdekat berdasarkan lokasi pengguna saat ini.
Kami akan menggunakan Laravel 5.0 untuk RESTful service dan akan mencakup konsep dasar, seperti route dan controller. Kami juga akan menentukan model kustom untuk mendukung integrasi MongoDB secara ActiveRecord-like. Mari kita mulai.
1. Pengaturan dasar
Saya akan berasumsi bahwa Anda sudah menginstal Composer dan installer Laravel terbaru. Jika Anda belum, kemudian ikuti dokumentasi Laravel 5.0 resmi. Proses instalasi hanya beberapa menit.
Dari command line, menavigasi ke lokasi mana Anda ingin membuat aplikasi untuk RESTful service dan jalankan perintah berikut:
laravel new mobilesinch
Setelah beberapa detik, command akan memberitahu Anda bahwa aplikasi mobilesinch telah berhasil dibuat. Menavigasi ke folder baru dan jalankan perintah berikut:
php artisan fresh
Aplikasi Laravel 5.0, secara default, bundling dengan perancah beberapa dasar untuk pengguna pendaftaran dan otentikasi. Perintah ini menangani menghapus ini karena kita ingin memulai dengan yang bersih.
Ada satu hal yang harus kita urus sebelum menulis kode aktual untuk RESTful service. Secara default, Laravel 5.0 bundling dengan middleware untuk cross-site request forgery (CSRF) perlindungan. Namun, karena kita tidak membangun sebuah situs web tetapi but a RESTful API, itu tidak masuk akal untuk memiliki tempat. Juga, dapat menyebabkan beberapa masalah sepanjang jalan.
Untuk aplikasi ini, cara terbaik untuk menghapusnya. Di root folder aplikasi, arahkan ke app/Http. dalam folder itu, ada sebuah file bernama Kernel.php. Buka dan Hapus baris berikut:
'App\Http\Middleware\VerifyCsrfToken',
Anda juga dapat menghapus WelcomeController.php, terletak di dalam app/Http/controller, serta tampilan welcome.blade.php default di dalam folder resources/views. Kami tidak akan menggunakan mereka, tapi Anda bisa meninggalkannya di sana jika Anda ingin. Hanya pastikan bahwa Anda meninggalkan view 503.blade.php di tempat seperti itu berguna untuk debug aplikasi.
2. Base
Model
Tutorial ini bertujuan untuk membuat aplikasi kencan memiliki fungsi seperti Tinder-like di mana Anda dapat menemukan pengguna dekat lokasi Anda saat ini. Untuk pekerjaan ini, API kebutuhan untuk melakukan pencarian berdasarkan lokasi pengguna, dikenal sebagai geospasial query. Sementara kita bisa melakukan ini dengan MySQL, standar industri bersandar ke arah MongoDB, dan saya pribadi lebih suka ini.
Daripada menggunakan Laravel's DB fasad, kita akan menciptakan kelas kami sendiri bahwa aplikasi model akan extend untuk melakukan query dalam MongoDB.
Ini akan menjadi kelas sederhana dan tidak akan diintegrasikan ke dalam Laravel's Eloquent model, meskipun kita bisa, saya ingin tetap sederhana untuk sementara waktu.
Step 1: Konfigurasi MongoDB
Sebelum menulis kelas untuk melakukan MongoDB queries, kita perlu untuk mengatur informasi database, seperti yang kita akan lakukan untuk MySQL atau PostgreSQL, atau server database lain.
Di dalam folder root config, membuat file baru dan nama itu mongodb.php. Tambahkan kode berikut:
<?php return [ 'host' => 'localhost', 'port' => 27017, 'user' => '', 'pass' => '', 'db' => 'mobilesinch' ];
Kami set host dan port untuk server MongoDB kita, jika ada, mengatur user dan password untuk koneksi, dan mendefinisikan database yang kita akan menggunakan, mobilesinch.
Karena MongoDB adalah document-oritented database dan schemaless, kita memerlukan tidak ada konfigurasi tambahan, tidak ada definisi migrasi atau apa pun untuk struktur tabel. It just works.
Langkah 2: Koneksi Database
Kami memiliki file konfigurasi di tempat dan sekarang saatnya untuk membuat kelas yang sebenarnya yang akan menangani interaksi dengan database.
Kelas ini akan melakukan query untuk MongoDB menggunakan ActiveRecord-seperti sintaks. Di dalam folder app/Http, buat Models baru, dan menambahkan file Base.php di dalamnya. Tambahkan kode berikut ini:
<?php namespace App\Http\Models; use Illuminate\Support\Facades\Config; class Base { private $_config = null; private $_conn = null; private $_db = null; public function __construct() { $this->_config = Config::get( 'mongodb' ); $this->_connect(); } private function _connect() {} }
Ini adalah bare-bones untuk Base
model class. Ini tidak extends dari apa-apa dan hanya bergantung pada Laravel's Config
facade untuk mengambil parameter konfigurasi yang kita buat sebelumnya.
Selanjutnya, kita perlu membuat koneksi dengan database. Tambahkan kode berikut untuk metode private _connect
:
$conn = 'mongodb://'.$this->_config['host']; if( ! empty( $this->_config['port'] ) ) { $conn .= ":{$this->_config['port']}"; } $options = array(); if( ! empty( $this->_config['user'] ) && ! empty( $this->_config['pass'] ) ) { $options['username'] = $this->_config['user']; $options['password'] = $this->_config['pass']; } try { $this->_conn = new \MongoClient( $conn, $options ); $this->_db = $this->_conn->{$this->_config['db']}; return true; } catch( \MongoConnectionException $e ) { $this->_conn = null; return false; }
Dalam metode ini, kami menciptakan koneksi string dan mengatur username dan password jika apapun yang diberikan. Kami kemudian menggunakan PHP MongoDB driver untuk membuat sambungan dan menetapkan database yang ditentukan di file konfigurasi.
Jika Anda sudah familiar dengan sintaks MongoDB dari baris perintah, metode ini adalah sama dengan memasuki konsol mongo dan ketik use mobilesinch
. Lihat dokumentasi PHP MongoDB resmi untuk informasi lebih lanjut.
Langkah 3: Helper Methods
Sebelum melanjutkan dengan operasi CRUD database, ada beberapa metode yang harus Base
class harus implementasikan Ini digunakan untuk mengatur filter, select statement, dan query variabel lain yang digunakan untuk melakukan operasi database. Mari kita mulai dengan menambahkan variabel member yang diperlukan. Di atas konstruktor kelas, tambahkan kode berikut:
private $_ws = array(); private $_sls = array(); private $_lmt = 99999; private $_ost = 0;
Ini adalah memegang untuk where, select, limit dan offset query database. Untuk set variabel member ini, buat metode setter berikut:
protected function _limit( $limit, $offset = null ) {} protected function _select( $select = "" ) {} protected function _where( $key, $value = null ) {}
Metode _limit
yang akan berguna untuk paginating hasil operasi READ. Pengguna dapat mengatur parameter limit
untuk menentukan jumlah record untuk mengambil dan opsional parameter offset
untuk menentukan halaman untuk membaca dari. Tambahkan kode berikut ke _limit
metode:
if ( $limit !== NULL && is_numeric( $limit ) && $limit >= 1 ) { $this->_lmt = $limit; } if ( $offset !== NULL && is_numeric( $offset ) && $offset >= 1 ) { $this->_ost = $offset; }
Metode _select
yang akan digunakan untuk menentukan field dari record query yang di baca harus di kembalikan. statement select harus disediakan sebagai string dipisahkan koma.
$fields = explode( ',', $select ); foreach ( $fields as $field ) { $this->_sls[trim( $field )] = true; }
Akhirnya, metode _where
yang akan digunakan untuk menyaring hasil query dan dapat menjadi array atau pasangan key/value.
if ( is_array( $key ) ) { foreach( $key as $k => $v ) { $this->_ws[$k] = $v; } } else { $this->_ws[$key] = $value; }
Kami sekarang memiliki dukungan untuk query filter dan limit, tetapi kami harus menambahkan beberapa metode helper lain. Yang pertama akan digunakan untuk menggabungkan apapun mana pernyataan set sebelum mengeluarkan query dengan query yang mana parameter.
Pada saat, ketika kita menulis metode CRUD kami, ini akan membuat lebih masuk akal. Di bagian bawah kelas, tambahkan private metode berikut:
private function _set_where( $where = null ) { if ( is_array( $where ) ) { $where = array_merge( $where, $this->_ws ); foreach ( $where as $k => $v ) { if ( $k == "_id" && ( gettype( $v ) == "string" ) ) { $this->_ws[$k] = new \MongoId( $v ); } else { $this->_ws[$k] = $v; } } } else if( is_string( $where ) ) { $wheres = explode( ',', $where ); foreach ( $wheres as $wr ) { $pair = explode( '=', trim( $wr ) ); if ( $pair[0] == "_id" ) { $this->_ws[trim( $pair[0] )] = new \MongoId( trim( $pair[1] ) ); } else { $this->_ws[trim( $pair[0] )] = trim( $pair[1] ); } } } }
Kelihatannya agak menakutkan, tapi itu sebenarnya cukup sederhana. Pertama-tama memeriksa apakah where
parameter adalah array. Jika, ini menggabungkan nilai yang tertentu dengan yang sudah ada yang menggunakan metode penolong _where
.
Namun, metode ini juga mendukung string untuk mengatur apa yang dikembalikan oleh operasi READ. String ini harus memiliki format berikut:
name=John,last_name=Smith
Contoh ini akan menjalankan query dan mengembalikan field dimana name
field di set ke John
and last_name
field di set ke Smith
Dicatat, bagaimanapun, bahwa untuk array atau string, kami memeriksa Jika field _id
ada. Jika hal ini terjadi dan string, kita membuat sebuah objek MongoId
baru dari itu. Id adalah objek di MongoDB dan membandingkan mereka untuk string akan return false
, itulah sebabnya mengapa konversi ini diperlukan.
Hal lain yang harus kita lakukan, adalah ulang semua parameter kueri setelah operasi telah dilakukan sehingga mereka tidak akan mempengaruhi pertanyaan berikutnya. Metode _flush
yang akan mengurus ini.
private function _flush() { $this->_ws = array(); $this->_sls = array(); $this->_lmt = 99999; $this->_ost = 0; }
Langkah 4: Operasi CRUD
Kami sekarang memiliki semua fungsi yang diperlukan untuk menyaring dan membatasi hasil query kami. Saatnya untuk operasi database yang sebenarnya, yang akan bergantung pada PHP MongoDB driver. Jika Anda tidak yakin tentang sesuatu, merujuk pada dokumentasi.
CREATE operasi
Operasi pertama yang kita akan mendukung yang membuat record dalam sistem. Tambahkan kode berikut untuk ke Base
class:
protected function _insert( $collection, $data ) { if ( is_object( $data ) ) { $data = ( array ) $data; } $result = false; try { if ( $this->_db->{$collection}->insert( $data ) ) { $data['_id'] = ( string ) $data['_id']; $result = ( object ) $data; } } catch( \MongoCursorException $e ) { $result = new \stdClass(); $result->error = $e->getMessage(); } $this->_flush(); return $result; }
Meskipun driver PHP mengharapkan data yang dimasukkan menjadi array, kelas kami akan mendukung array dan objek. Kami pertama memverifikasi yang dilewatkan ke kami dan dibuang sesuai. Selanjutnya, kami menerapkan metode _find
untuk mengambil daftar record.
READ operasi
Kita akan implement dua metode read, salah satu yang akan digunakan untuk mengambil satu recrod data sementara yang lain akan digunakan untuk mengambil daftar record. Mari kita mulai dengan former.
protected function _findOne( $collection, $where = array() ) { $this->_set_where( $where ); $row = $this->_db->{$collection}->findOne( $this->_ws, $this->_sls ); $this->_flush(); return ( object ) $row; }
Kita mendefinisikan mana clause untuk query dan menggunakan PHP MongoDB driver untuk melakukan operasi findOne
. Kami kemudian flush parameter kueri dan kembali record sebagai objek.
PHP MongoDB driver mengembalikan hasil sebagai array sementara saya pribadi lebih suka objek. Itulah alasan yang benar.
Selanjutnya, kami menerapkan metode _find
untuk mengambil daftar record.
protected function _find( $collection, $where = array() ) { $this->_set_where( $where ); $docs = $this->_db->{$collection} ->find( $this->_ws, $this->_sls ) ->limit( $this->_lmt ) ->skip( $this->_ost ); $this->_flush(); $result = array(); foreach( $docs as $row ) { $result[] = ( object ) $row; } return $result; }
Dalam metode _find
, kami menggunakan metode find
driver, menetapkan limit
query dan skip
parameter untuk mendukung pagination.
Metode ini, namun, mengembalikan sebuah objek MongoCursor
, yang kita kemudian iterate untuk mendapatkan record sebenarnya. Seperti sebelumnya, kami cast setiap record sebagai objek, menambahkan ke array hasil.
UPDATE operasi
Kita sudah memiliki dukungan untuk create dan read data dari database. Kita sekarang perlu untuk dapat update record dan menambahkan atau mengubah record data. Membuat _update
metode baru dan menerapkannya sebagai berikut:
protected function _update( $collection, $data, $where = array() ) { if ( is_object( $data ) ) { $data = ( array ) $data; } $this->_set_where( $where ); if ( array_key_exists( '$set', $data ) ) { $newdoc = $data; } else { $newdoc = array( '$set' => $data ); } $result = false; try { if( $this->_db->{$collection}->update( $this->_ws, $newdoc ) ) { $result = ( object ) $data; } } catch( \MongoCursorException $e ) { $result = new \stdClass(); $result->error = $e->getMessage(); } $this->_flush(); return $result; }
Seperti dengan CREATE operasi, kami mendukung array dan object, yang berarti kita periksa dan cast sesuai itu. Kami menggabungkan mana clause pass ke metode menggunakan metode helper. Sisanya tidak berbeda daripada metode _insert
sudah dibuat.
Ada hal yang khusus untuk dicatat. Ketika kita memperbarui dokumen MongoDB dan pass data ke _update
metode, dokumen akan diganti. Jika kita hanya memperbarui satu bidang dan pass data Field, dokumen akan menjadi bidang itu. Inilah sebabnya mengapa kita perlu membuat sebuah array dengan $set
key dan informasi tambahan. Hasilnya adalah bahwa kami tidak akan diganti dengan informasi baru.
DELETE pengoperasian
Akhirnya, driver harus mendukung operasi DELETE untuk menghapus dokumen dari database.
protected function _remove( $collection, $where = array() ) { $this->_set_where( $where ); $result = false; try { if ( $this->_db->{$collection}->remove( $this->_ws ) ) { $result = true; } } catch( \MongoCursorException $e ) { $result = new \stdClass(); $result->error = $e->getMessage(); } $this->_flush(); return $result; }
Seperti sebelumnya, kita menetapkan mana klausul untuk Hapus operasi dan bergantung pada PHP MongoDB driver untuk melakukan operasi remove
pada database.
Dan that's it untuk model Base
kami. Banyak kode, tetapi kita sekarang dapat melakukan operasi di MongoDB untuk model yang mewarisi dari kelas Base
.
3. Session
Model
Model Session
akan membuat, menghapus, dan menemukan sebuah session dalam database. Buat sebuah file baru di folder Models aplikasi, nama itu Session.php dan tambahkan kode berikut untuk itu:
<?php namespace App\Http\Models; class Session extends Base { private $_col = "sessions"; public function create( $user ) { $this->_where( 'user_id', ( string ) $user->_id ); $existing = $this->_findOne( $this->_col ); if ( !empty( ( array ) $existing ) ) { $this->_where( 'user_id', ( string ) $user->_id ); $this->_remove( $this->_col ); } $session = new \stdClass(); $session->user_id = ( string ) $user->_id; $session->user_name = $user->name; $session = $this->_insert( $this->_col, $session ); return $session; } public function find( $token ) { $this->_where( '_id', $token ); return $this->_findOne( $this->_col ); } public function remove( $token ) { $this->_where( '_id', $token ); return $this->_remove( $this->_col ); } }
Model ini extend dari kelas Base
kita buat sebelumnya untuk mendukung operasi MongoDB. Ini juga menetapkan koleksi untuk digunakan untuk sessions
.
create
metode ini digunakan untuk membuat rekor sesi pengguna. Sebelum mencoba untuk membuat itu, metode memverifikasi jika pengguna telah memiliki session aktif. Jika tidak, itu hilangkan dari database dan buat rekor baru dengan pass ke dalam informasi pengguna.
Metode find
digunakan untuk mengambil session record dari database menggunakan token session. Perhatikan bahwa ini hanya menetapkan mana klausul untuk permintaan dan mendelegasikan tugas mencari record untuk metode _findOne
kelas Base
.
Untuk mengakhiri session use, kami menerapkan metode remove
. Menggunakan token session, itu mendelegasikan angkat berat untuk metode _remove
kelas Base
. Perhatikan bahwa model membuat tidak ada pemeriksaan token session yang dilewatkan. Ini harus ditangani oleh controller. Satu-satunya kepedulian untuk model adalah manipulasi data.
4. Model User
Model lain bahwa kami REST API kebutuhan adalah salah satu untuk menangani pengguna terkait interaksi. Di dalam folder aplikasi Models, membuat file User.php baru, dan tambahkan kode berikut untuk itu:
<?php namespace App\Http\Models; use App\Http\Models\Base as Model; class User extends Model { private $_col = "users"; private $_error = null; public function get( $where ) {} public function get_error() {} public function create( $user ) {} public function remove( $id ) {} public function retrieve( $id, $distance, $limit = 9999, $page = 1 ) {} public function update( $id, $data ) {} }
User
model ini sedikit lebih rumit. Mari kita mulai dengan metode untuk mengambil users. Metode get
akan bertanggung jawab untuk mengambil satu record data, menggunakan id user. Tambahkan kode berikut untuk metode get
:
if ( is_array( $where ) ) { return $this->_findOne( $this->_col, $where ); } else { $this->_where( '_id', $where ); return $this->_findOne( $this->_col ); }
Kami menganggap bahwa dalam kasus where
parameter tidak array, itu adalah id pengguna. Metode get
kemudian mendelegasikan tugas mencari record untuk metode _findOne
kelas Base
.
Metode get_error
adalah metode helper yang akan memberikan informasi lebih lanjut tentang kegagalan controller dalam model.
return $this->_error;
Terakhir membaca operasi di User
model adalah satu untuk retrieve
metode. Ini akan mengambil daftar record. Tambahkan kode berikut untuk retrieve
metode:
if ( !empty( $id ) && !empty( $distance ) ) { $this->_where( '_id', $id ); $this->_select( 'location' ); $user = $this->_findOne( $this->_col ); if ( empty( ( array ) $user ) ) { $this->_error = "ERROR_INVALID_USER"; return false; } $this->_where( '$and', array( array( '_id' => array( '$ne' => new \MongoId( $id ) ) ), array( 'location' => array( '$nearSphere' => array( '$geometry' => array( 'type' => "Point", 'coordinates' => $user->location['coordinates'] ), '$maxDistance' => ( float ) $distance ) ) ) ) ); } $this->_limit( $limit, ( $limit * --$page ) ); return $this->_find( $this->_col );
Metode ini mendukung pagination dan geospasial query. Jika parameter id
dan distance
di passing, itu upaya untuk mencari terdekat pengguna berdasarkan lokasi pengguna.
Jika id
tidak cocok record, mengembalikan false
. Jika ada pengguna, it mempersiapkan query geospasial menggunakan indeks 2dsphere MongoDB.
Perhatikan bahwa kami juga pengaturan query tidak boleh kembali pengguna pencocokan _id
pengguna melakukan pencarian. Akhirnya, ini menetapkan limit query dan parameter offset, mendelegasikan task metode _find
kelas Base
.
Untuk menghapus users, kita perlu untuk mengimplementasikan metode remove
. Tambahkan kode berikut untuk remove
metode:
$this->_where( '_id', $id ); $user = $this->_findOne( $this->_col ); if ( empty( ( array ) $user ) ) { $this->_error = "ERROR_INVALID_ID"; return false; } else { $this->_where( '_id', $id ); if ( !$this->_remove( $this->_col ) ) { $this->_error = "ERROR_REMOVING_USER"; return false; } } return $user;
Kami memeriksa bahwa _id
diberikan sesuai dengan user yang ada dan upaya untuk menghapus menggunakan metode _remove
kelas Base
. Jika ada yang tidak beres, kita mengatur properti _error
model dan mengembalikan nilai false
.
Operasi lain model kita harus mendukung adalah pembuatan record pengguna. Tambahkan kode berikut untuk create
metode:
if ( is_array( $user ) ) { $user = ( object ) $user; } $this->_where( '$or', array( array( "email" => $user->email ), array( "mobile" => $user->mobile ) ) ); $existing = $this->_findOne( $this->_col ); if ( empty( ( array ) $existing ) ) { $user = $this->_insert( $this->_col, $user ); } else { $user = $existing; } $user->_id = ( string ) $user->_id; return $user;
Dalam metode ini, kami pastikan sudah tidak ada user yang terkait dengan email
atau mobile
yang diberikan. Jika itu benar, kita kembali pengguna yang sesuai. Jika tidak, kami mendelegasikan tugas untuk membuat pengguna untuk metode _insert
kelas Base
.
Sebelum kita kembali record user, kami cast _id
ke string. Kenapa bisa begitu? Obyek yang dikembalikan kepada kita mendefinisikan field _id
sebagai objek MongoId. Aplikasi klien, namun, tidak perlu objek ini.
User
model juga perlu untuk mendukung memperbarui user record. Tambahkan kode berikut untuk metode update
:
if ( is_array( $data ) ) { $data = ( object ) $data; } if ( isset( $data->email ) || isset( $data->mobile ) ) { $this->_where( '$and', array( array( '_id' => array( '$ne' => new \MongoId( $id ) ) ), array( '$or' => array( array( 'email' => ( isset( $data->email ) ) ? $data->email : "" ), array( 'mobile' => ( isset( $data->mobile ) ) ? $data->mobile : "" ) ) ) ) ); $existing = $this->_findOne( $this->_col ); if ( !empty( ( array ) $existing ) && $existing->_id != $id ) { $this->_error = "ERROR_EXISTING_USER"; return false; } } $this->_where( '_id', $id ); return $this->_update( $this->_col, ( array ) $data );
Seperti kelas Base
, metode update
menerima array dan object sebagai data untuk user. Hal ini membuat metode jauh lebih fleksibel.
Sebelum kita memperbarui user record, kami memastikan bahwa user email
dan mobile
tidak sudah digunakan oleh user lain. Jika itu terjadi, kami mengatur kesalahan untuk EXISTING_USER
dan mengembalikan nilai false
. Jika tidak, kami mendelegasikan operasi update untuk kelas Base
.
5. BaseController
Class
Seperti aplikasi model mewarisi dari class Base
, controller juga mewarisi dari kelas induk yang umum, bukan class Controller
Laravel's. class BaseController
ini tidak akan di mana saja dekat kompleksitas model Base
meskipun.
Class hanya dapat digunakan untuk menangani beberapa tugas yang sederhana. Untuk membuat class, kita menggunakan Laravel's artisan command. Dari command line, menavigasi ke root dari aplikasi Anda dan eksekusi perintah berikut:
php artisan make:controller BaseController --plain
Ini akan membuat sebuah file bernama BaseController.php di dalam aplikasi Controllers folder dalam folder app/Http. Karena kita menggunakan flag --plain
, controller tidak akan memiliki metode, yang adalah apa yang kita inginkan.
Controller ini tidak menggunakan Request
class sehingga Anda langsung saja hapus baris berikut:
use Illuminate\Http\Request;
Karena kita membutuhkan akses ke Session
model, tambahkan baris berikut ke Deklarasi BaseController
class:
use App\Http\Models\Session as SessionModel;
Sekarang kita siap untuk menerapkan metode BaseController
class. Memulai dengan menambahkan metode berikut di dalam deklarasi class:
protected function _check_session( $token = "", $id = "" ) { $result = false; if ( !empty( $token ) ) { $SessionModel = new SessionModel(); $session = $SessionModel->find( $token ); if ( !empty( ( array ) $session ) ) { if ( !empty( $id ) ) { if ( $session->user_id == $id ) { $result = $session; } } else { $result = $session; } } } return $result; } protected function _response( $result ) { if ( is_object( $result ) && property_exists( $result, "status" ) ) { return response()->json( $result, $result->status ); } else { return response()->json( $result ); } }
Metode _check_session
digunakan untuk memverifikasi token session, yang passing sebagai argumen pertama. Beberapa tugas dalam aplikasi memerlukan user untuk login. Sebagai contoh, ketika memperbarui record user, sesuai dengan session aktif kebutuhan pengguna untuk menyesuaikan _id
dari catatan yang perlu di update.
Implementasi cukup sederhana. Kami mengambil sesi untuk token session dan, jika id pengguna yang terkait dengan sesssion cocok id yang akan diteruskan di sebagai argumen kedua, kita kembalikan session. Jika tidak, kita kembalikan nilai false
.
Metode helper lain mengurus pengiriman hasil kembali ke klien yang mengkonsumsi API. Saat ini, kami hanya mendukung JSON. Jika result untuk kembali adalah objek dan memiliki status parameter, kita mengatur menggunakan metode helper Laravel's response
. Sebaliknya, kita hanya return hasilnya.
6. SessionController
Class
Controller berikutnya kami akan menerapkan adalah salah satu yang menangani permintaan untuk Sessions
resource. Dari baris perintah, menavigasi ke root dari aplikasi Anda dan eksekusi perintah berikut:
php artisan make:controller SessionController --plain
Ini akan menciptakan sebuah file baru yang bernama SessionController.php di dalam aplikasi Controllers folder dalam folder app/Http. Sebelum kita implement class ini, kita perlu untuk mengurus beberapa hal.
Class SessionController
saat ini mewarisi dari kelas Controller
Laravel's. Kita perlu untuk mengatur hal ini untuk menggunakan kelas BaseController
kami. Ini berarti kita perlu mengganti
use App\Http\Controllers\Controller;
dengan
use App\Http\Controllers\BaseController;
Kita juga perlu mengubah extends
klausul class. Alih-alih extend dari Controller
, pastikan bahwa kelas Anda extend kelas BaseController
. Kita juga perlu untuk menyertakan model-model yang digunakan dalam controller. Di bawah Deklarasi terakhir, tambahkan baris berikut:
use App\Http\Models\Session as SessionModel; use App\Http\Models\User as UserModel;
Biasanya, kita hanya akan menggunakan SessionModel
, tetapi Anda akan melihat mengapa kami juga menggunakan UserModel
beberapa saat lagi. Sedangkan untuk kelas controller sendiri, tambahkan kode berikut:
private $_model = null; public function __construct() { $this->_model = new SessionModel(); } public function create( Request $request ) {} public function destroy( $token ) {}
Kami menetapkan objek model
controller dalam konstruktor dan menyatakan beberapa metode, yang merupakan tindakan yang didukung oleh Sessions
resource.
Langkah 1: Session Removal
Untuk menghilangkan session user, kami hanya menggunakan token session, yang diberikan sebagai parameter dalam URL resource. Kami akan menyatakan ini kemudian di route aplikasi. Di dalam metode destroy
, tambahkan kode berikut:
$result = new \stdClass(); if ( !$this->_model->remove( $token ) ) { $result->error = "ERROR_REMOVING_SESSION"; $result->status = 403; } return $this->_response( $result );
Metode menggunakan metode remove
SessionModel
dan mengembalikan hasil yang menggunakan metode _response
kelas BaseController
. Jika menghapus session berhasil, kita return sebuah objek kosong. Jika terjadi kesalahan, kita return kesalahan dengan kode 403 status.
Langkah 2: Session Creation
Metode untuk membuat session sedikit lebih rumit. Perhatikan bahwa dalam deklarasi metode kita menggunakan Laravel's Request
objek. Kami menggunakan objek ini untuk mengakses POST parameter request. Di dalam metode create
, tambahkan kode berikut:
$email = $request->get( 'email' ); $mobile = $request->get( 'mobile' ); $fbId = $request->get( 'fbId' ); $result = new \stdClass(); if ( ( empty( $email ) && empty( $mobile ) ) || empty( $fbId ) ) { $result->error = "ERROR_INVALID_PARAMETERS"; $result->status = 403; } else {} return $this->_response( $result );
Kami belum membuat objek session, namun, karena ada sesuatu yang kita perlu membahas dulu. Aplikasi akan menggunakan hanya Facebook Login . Dari Facebook SDK, kita mendapatkan informasi user ketika melakukan operasi login. Dalam API's Session
resource POST handler, kita perlu untuk mendukung dua hal:
- mulai session untuk user
- buat user saat tidak ada dan kemudian mulai sesi
Hal ini juga alasan termasuk UserModel
di controller. Pada else
clause kosong diatas, tambakan kode berikut
$UserModel = new UserModel(); $where = ( !empty( $email ) ) ? array( 'email' => $email ) : array( 'mobile' => $mobile ); $user = $UserModel->get( $where ); if ( empty( ( array ) $user ) ) { } else { if ( $fbId != $user->fbId ) { $result->error = "ERROR_INVALID_CREDENTIALS"; $result->status = 403; } } if ( !property_exists( $result, "error" ) ) { $result = $this->_model->create( $user ); $result->token = $result->_id; unset( $result->_id ); }
Kami pertama kali Periksa user yang ada dengan passing dalam email
atau mobile
. Jika ada user, kami memverifikasi bahwa Facebook ID yang diberikan sesuai dengan Facebook ID untuk record user. Jika itu terjadi, kami membuat objek sesi. Jika tidak, metode return kesalahan INVALID_CREDENTIALS
dengan kode 403
status.
Mulai session sekarang lengkap. Catatan bahwa ini bukan ekstra aman. Namun, untuk tujuan dari tutorial ini, ia akan bekerja baik.
Untuk kasus ketika ada tidak ada user yang terkait dengan passing dalam email
atau mobile
, kami ingin buat record baru. Di atas if
kosong di atas klausul, tambahkan kode berikut:
name = $request->get( 'name' ); $gender = $request->get( 'gender' ); $location = $request->get( 'location' ); if ( empty( $name ) || empty( ( array ) $location ) || empty( $gender ) ) { $result->error = "ERROR_INVALID_PARAMETERS"; $result->status = 403; } else { if ( gettype( $location ) == "string" ) { $location = json_decode( $location ); } $locObj = new \stdClass(); $locObj->type = "Point"; $locObj->coordinates = array( $location->lon, $location->lat ); $user->name = $name; $user->fbId = $fbId; $user->email = $email; $user->mobile = $mobile; $user->gender = $gender; $user->location = $locObj; $user = $UserModel->create( $user ); }
Kami pertama kali mengambil seluruh parameter yang diperlukan dari permintaan dan kemudian memeriksa jika parameter location
diberikan sebagai sebuah objek JSON atau objek JSON dikodekan (string). Metode mengharapkan parameter ini harus dalam format berikut:
{ "lat" : 37.427208696456866, "lon" : -122.17097282409668 }
Kita kemudian mengubah lokasi ini ke lokasi 2dSphere MongoDB. Untuk mengeksekusi query geospasial, bidang ini harus memiliki format berikut:
{ "type" : "Point" "coordinates" : [ -122.17097282409668, 37.427208696456866 ] }
Kita bisa meminta klien untuk mengirim lokasi dalam format ini. Namun, itu lebih baik bahwa kita tidak membebani klien dengan reformatting lokasi pengguna karena ini khusus untuk pelaksanaan kami.
Setelah mengatur objek lokasi, kami memeriksa bahwa pengguna diperlukan parameter ada dan, jika itu terjadi, kami membuat objek pengguna baru menggunakan metode create
kelas UserModel
.
Thats it. Meskipun kita dapat memulai session dengan mengirim hanya email
dan fbId
parameter atau mobile
dan fbId
parameter, jika session informasi pengguna yang diberikan, handler kami akan mengurus membuat user baru bila diperlukan dan mulai session.
7. UserController
class
Controller terakhir yang memerlukan aplikasi yang bertanggung jawab atas penanganan Users
resource. Sekali lagi, kita menggunakan Laravel's artisan command. Dari command line, menavigasi ke root dari aplikasi Anda dan eksekusi perintah berikut:
php artisan make:controller UserController --plain
Ini akan membuat file UserController.php di dalam aplikasi Controllers folder dalam folder app/Http. Seperti dengan kelas SessionController
, pastikan bahwa UserController
kelas mewarisi dari BaseController
dan bahwa hal itu termasuk kelas UserMo
del. Di dalam deklarasi kelas, tambahkan kode berikut:
private $_model = null; public function __construct() { $this->_model = new UserModel(); } public function create( Request $request ) {} public function get( Request $request, $id ) {} public function remove( Request $request, $id ) {} public function retrieve( Request $request ) {} public function update( Request $request, $id ) {}
Seperti dengan kelas SessionController
, kami menginisialisasi objek model dan deklarasi metode yang akan didukung oleh Users
resource. Mari kita mulai dengan yang untuk GET operasi. Dalam metode get
, tambahkan kode berikut:
$token = $request->get( 'token' ); $result = new \stdClass(); if ( !$this->_check_session( $token ) ) { $result->error = "PERMISSION_DENIED"; $result->status = 403; } else { $result = $this->_model->get( $id ); } return $this->_response( $result );
Untuk mengambil record dari sistem, kami meminta bahwa pengguna memiliki session aktif. Tidak harus cocok dengan id pengguna yang diperoleh. Jika pengguna tidak memiliki session berlaku, kita return kesalahan PERMISSION_DENIED
dengan kode 403
status. Sebaliknya kita return record user sebagai sebuah objek JSON.
Selanjutnya, untuk daftar users, kita perlu untuk mengimplementasikan metode retrieve
. Tambahkan kode berikut untuk retrieve
metode:
$token = $request->get( 'token' ); $distance = $request->get( 'distance' ); $session = $this->_check_session( $token ); $result = $this->_model->retrieve( ( isset( $session->user_id ) ? $session->user_id : "" ), $distance, $request->get( 'limit' ), $request->get( 'page' ) ); if ( !is_array( $result ) && !$result ) { $result = new \stdClass(); $result->error = $this->_model->get_error(); $result->status = 403; } return $this->_response( $result );
Kita mulai dengan mengambil parameter request, token session user dan parameter jarak khususnya. Metode ini, namun, tidak memerlukan session aktif. Jika session berlaku, kami passing id pengguna untuk retrieve
metode UserModel
kelas.
Jika distance
parameter passing, geospasial query akan di eksekusi. Jika tidak, find
query akan di eksekusi. Jika terjadi kesalahan, kita return kesalahan dari model dan kembali ke user dengan kode 403
status. Jika tidak, kami mengembalikan array yang berisi user ditemukan.
Pembuatan user akan memetakan Users
resource POST operasi. Tambahkan kode berikut untuk create
metode:
$email = $request->get( 'email' ); $fbId = $request->get( 'fbId' ); $gender = $request->get( 'gender' ); $location = $request->get( 'location' ); $mobile = $request->get( 'mobile' ); $name = $request->get( 'name' ); if ( gettype( $location ) == "string" ) { $location = json_decode( $location ); } $locObj = new \stdClass(); $locObj->type = "Point"; $locObj->coordinates = array( $location->lon, $location->lat ); $result = new \stdClass(); if ( empty( $name ) || empty( ( array ) $location ) || empty( $fbId ) || empty( $gender ) || ( empty( $email ) && empty( $mobile ) ) ) { $result->error = "ERROR_INVALID_PARAMETERS"; $result->status = 403; } else { $user = array( "email" => $email, "fbId" => $fbId, "gender" => $gender, "location" => $locObj, "mobile" => $mobile, "name" => $name ); $result = $this->_model->create( $user ); } return $this->_response( $result );
Kita pertama kali mengambil informasi yang diperlukan bagi user dan, seperti dalam session creation handler, kita mengubah lokasi pengguna ke format yang sesuai.
Setelah ini, kami memeriksa bahwa informasi yang diperlukan adalah sesuai. Perhatikan bahwa meskipun email
dan mobile
field opsional, setidaknya satu harus ada.
Setelah pemeriksaan, kita memanggil metode create
kelas UserModel
untuk insert pengguna baru dalam database. Akhirnya, kita return pengguna baru atau error.
Untuk menghapus pengguna, kita perlu untuk mengimplementasikan metode remove
. Tambahkan kode berikut untuk remove
metode:
$token = $request->get( 'token' ); $result = new \stdClass(); if ( !$this->_check_session( $token, $id ) ) { $result->error = "PERMISSION_DENIED"; $result->status = 403; } else { $result = $this->_model->remove( $id ); if ( !$result ) { $result = new \stdClass(); $result->error = $this->_model->get_error(); $result->status = 403; } } return $this->_response( $result );
Ini adalah salah satu metode di mana kita ingin _id
pengguna akan dihapus untuk mencocokkan _id
pengguna dengan session aktif. Ini hal pertama yang kami memverifikasi. Jika itu terjadi, kita mendelegasikan kepada model remove
metode. Jika tidak, kami set error untuk PERMISSION_DENIED
dan mengirim hasilnya kembali ke user.
Akhirnya, mari kita imlement operasi update user. Di dalam metode update
, tambahkan kode berikut:
$token = $request->get( 'token' ); $data = new \stdClass(); if ( !empty( $email = $request->get( 'email' ) ) ) { $data->email = $email; } if ( !empty( $fbId = $request->get( 'fbId' ) ) ) { $data->fbId = $fbId; } if ( !empty( $gender = $request->get( 'gender' ) ) ) { $data->gender = $gender; } if ( !empty( $location = $request->get( 'location' ) ) ) { if ( gettype( $location ) == "string" ) { $location = json_decode( $location ); } $locObj = new \stdClass(); $locObj->type = "Point"; $locObj->coordinates = array( $location->lon, $location->lat ); $data->location = $locObj; } if ( !empty( $mobile = $request->get( 'mobile' ) ) ) { $data->mobile = $mobile; } if ( !empty( $name = $request->get( 'name' ) ) ) { $data->name = $name; } $result = new \stdClass(); if ( !$this->_check_session( $token, $id ) ) { $result->error = "PERMISSION_DENIED"; $result->status = 403; } else { $result = $this->_model->update( $id, $data ); if ( !$result ) { $result = new \stdClass(); $result->error = $this->_model->get_error(); $result->status = 403; } } return $this->_response( $result );
Memvalidasi data yang telah berlalu dalam dan menetapkan objek yang tepat untuk apa yang harus update. Dalam kasus parameter location
, kita reformat dahulu.
Sekali lagi, metode ini harus hanya dapat diakses oleh user dengan sesi aktif yang berkaitan dengan _id
mereka sendiri. Ini berarti bahwa kita pertama periksa ini terjadi.
Kami kemudian memanggil metode update
kelas UserModel
dan mengembalikan hasil kepada klien.
8. Aplication Router
Yang terakhir potongan kode API kami sekarang lengkap. Kami memiliki controller dan model di tempat. Hal terakhir yang harus kita lakukan adalah mapping request yang masuk ke Endpoint yang sesuai.
Untuk itu, kita perlu mengedit file routes.php aplikasi kita. Terletak di dalam folder app/Http. Jika Anda membukanya, Anda harus melihat sesuatu seperti ini:
Route::get( '/', 'WelcomeController@index' );
Ketika aplikasi menerima sebuah GET request tanpa resource yang ditentukan, index
metode WelcomeController
kelas harus menanganinya. Namun, Anda mungkin sudah dihapus WelcomeController
pada awal tutorial ini. Jika Anda mencoba untuk menavigasi ke ini endpoint di browser, Anda akan mendapatkan kesalahan. Mari kita ganti baris terakhir dengan kode berikut:
Route::post( 'sessions', 'SessionController@create' ); Route::delete( 'sessions/{token}', 'SessionController@destroy' ); Route::delete( 'users/{id}', 'UserController@remove' ); Route::get( 'users', 'UserController@retrieve' ); Route::get( 'users/{id}', 'UserController@get' ); Route::post( 'users', 'UserController@create' ); Route::put( 'users/{id}', 'UserController@update' );
Kita map request API untuk metode sebelumnya ditambahkan ke controller kami. Sebagai contoh, berikut panggilan
[ DELETE ] - http://YOUR_API_URL/sessions/abc
menerjemahkan ke DELETE request ke URL tertentu. Ini berarti bahwa di SessionController
metode delete
akan dipanggil dengan token abc
.
Kesimpulan
That's it untuk RESTful API menggunakan Laravel 5.0. Kami memiliki dukungan untuk pengguna dan manajemen session, yang adalah apa yang kita butuhkan untuk menerapkan klien iOS.
Dalam bagian selanjutnya dari tutorial ini, Jordan akan menunjukkan kepada Anda bagaimana untuk mengintegrasikan API ini dalam aplikasi iOS. Dia juga akan menunjukkan Anda bagaimana untuk mengintegrasikan Sinch SDK untuk panggilan suara dan pesan.
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post