Rest Api Kullanımı

03.05.2019

JSON 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/

© 2019 Tüm Hakları Saklıdır. Codesenior.COM