Rest Api Kullanımı
03.05.2019JSON Rest API'de aşağıdaki kriterler önem arzetmektedir:
1- NULL yerine boş string gönderilmelidir.
2- Date türü için ISO-8601 formatına göre gönderilmelidir.
3- Multiline string için base64 encoding yapılabilir.
4- Success için aşağıdaki gibi bir sonuç dönülmelidir:
{
"data": {
"id":1000,
"first_name": "Ahmet Yılmaz"
}
}
Eğer birden fazla sonuç gelecekse aşağıdaki gibi döndürülmelidir:
{
"data": [{
"id":1000,
"first_name": "Ahmet Yılmaz"
},
{
"id":1001,
"first_name": "Hakkı Yılmaz"
}]
}
5- Naming Convention olarak, bu örneklerde görüldüğü üzere bir property birden fazla kelimeden oluşuyorsa, snake_case dediğimiz teknik kullanılması tavsiye edilmektedir. Ancak Java ve Javascript'te ise camelCase kullanılması tavsiye edilmektedir.
6- Error sonuç için aşağıdaki gibi bir sonuç dönülmelidir:
{
"error": {
"code": 404,
"message: "ID not found"
}
}
Aynı şekilde birden fazla dönülecekse aşağıdaki gibi dönülmesi tavsiye edilmektedir: Burada dikkat edilmesi gereken husus şudur: Parametre error yerine errors şeklinde kullanıldı.
{
"errors": [{
"code": 404,
"message: "ID not found"
},
{
"code": 400
"message: "Bad request"
}]
}
7- Rest API de kullanılması tavsiye edilen HTTP status kodları şunlardır:
- 200 -> OK
- 201 -> Created
- 204 -> Deleted gibi işlemlerde boş içerik döndermek için kullanılmaktadır.
- 304 -> Not Modified
- 400 -> Bad Request
- 401 -> Unauthorized
- 403 -> Forbidden
- 404 -> Not found
- 500 -> Internal server error. (Bu hata kodunu kullanıcıya iletmemek en doğru yöntemdir)
Örnek PHP Uygulaması
Öncelikle Vue.js ve Axios ile yapılan client kod kısmına bakalım:
<template>
<div>
<div class="row">
<div class="col-sm-12">
<input type="checkbox" class="form-check-input" id="chk_other" @change="check($event)">
<label class="form-check-label" for="chk_other">Proje İçerik türü yoksa ekleyiniz</label>
</div>
</div>
<div v-show="showProjectContentInput">
<div class="row">
<div class="form-group col-sm-8">
<input type="text" v-model="projectContent" placeholder="Proje türünü buraya yazınız"
class="form-control"/>
</div>
<div class="form-group col-sm-4">
<input type="button" class="btn btn-primary" v-on:click="addNewType()" value="Kaydet">
</div>
</div>
<div class="row" v-show="showError">
<div class="col-sm-12">
<div class="alert-danger pad margin-bottom-5 border-radius">
{{ errorMessage }}
</div>
</div>
</div>
<div class="row" v-show="showSuccess">
<div class="col-sm-12">
<div class="alert-success pad margin-bottom-5 border-radius">
{{ successMessage }}
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {},
/*
* The component's data.
*/
data() {
return {
showProjectContentInput: false,
showError: false,
errorMessage: " ",
showSuccess: false,
successMessage: " ",
projectContent: ''
};
},
/**
* Prepare the component (Vue 2.x).
*/
mounted() {
this.prepareComponent();
},
methods: {
/**
* Prepare the component (Vue 2.x).
*/
prepareComponent() {
},
check() {
this.showProjectContentInput = this.showProjectContentInput === false;
},
addNewType() {
if (this.projectContent.length < 4) {
this.errorMessage = 'Minimum 3 karakter girilmelidir';
this.showError = true;
} else {
const data = {
name: 'Client Token',
scopes: []
};
axios.post('/oauth/personal-access-tokens', data)
.then(response => {
var config = {
headers: {'Authorization': "Bearer " + response.data.accessToken}
};
axios.post('/api/v1/project-contents', {'name': this.projectContent},config).then(response => {
this.successMessage = response.data.data.message;
this.showSuccess = true;
this.showError = false;
setTimeout(function(){
window.location.reload();
},2000);
}).catch(error => {
this.errorMessage = error.response.data.error != null ? error.response.data.error.message : error.message;
this.showError = true;
this.showSuccess = false;
});
})
.catch(error => {
this.errorMessage=error.message;
this.showError = true;
this.showSuccess = false;
});
}
}
}
}
</script>
PHP Kodları:
use App\Repositories\ProjectContentRepository;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
class ProjectContentController
{
/** @var ProjectContentRepository */
private $projectContentRepository;
public function __construct(ProjectContentRepository $projectContentRepository)
{
$this->projectContentRepository = $projectContentRepository;
}
public function store(Request $request)
{
if (request()->wantsJson()) {
try {
$userId = Auth::user()->id;
$name = $request->input('name');
if (!isset($name) || strlen($name) < 4) {
return response()->json(['error' =>
['code' => '400', 'message' => 'Minimum 3 karakter girilmelidir']], 400);
}
$existingContent = $this->projectContentRepository->findByField('name', $name)->first();
if ($existingContent != null) {
return response()->json(['error' =>
['code' => '400', 'message' => 'Bu isimde bir proje içerik vardır']], 400);
}
$this->projectContentRepository->create(['name' => $name, 'user_id' => $userId]);
return response()->json(['data' => ['message' => 'Başarılı bir şekilde eklendi']]);
} catch (\Exception $e) {
Log::error($e->getMessage());
return response()->json(['error' => ['code' => '400', 'message' => 'Beklenmeyen bir hata oluştu']], 400);
}
} else {
return response()->json(['error' => ['code' => '415', 'message' => 'Method not supported']], 415);
}
}
}
8- Diğer önemli bilgiler için https://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/