Apa yang ditawarkan HATEOAS untuk kemampuan menemukan dan memisahkan selain kemampuan untuk mengubah struktur URL Anda lebih atau kurang secara bebas?

62

Akhir-akhir ini saya telah membaca tentang Hypermedia sebagai Engine of Application State (HATEOAS), kendala yang diklaim membuat API web "benar-benar tenang". Pada dasarnya intinya termasuk tautan dengan setiap respons terhadap kemungkinan transisi yang dapat Anda lakukan dari kondisi saat ini.

Izinkan saya menggambarkan apa yang HATEOAS didasarkan pada pemahaman saya - dan tolong perbaiki saya jika saya melewatkan sesuatu.

/
    GET: {
        "_links": {
            "child": [
                { "href": "http://myapi.com/articles", "title": "articles" }
            ]
        }
    }

/articles?contains=HATEOAS
    GET: {
        "_items": [
            { "uri": "http://myapi.com/articles/0", "title": "Why Should I Care About HATEOAS?" },
            { "uri": "http://myapi.com/articles/1", "title": "HATEOAS: Problem or Solution?" }
        ],
        "_links": {
            "self": { "href": "http://myapi.com/articles", "title": "articles" },
            "parent": { "href": "http://myapi.com/", "title": "home" }
        }
    }

    POST: {
        "title": "A New Article",
        "body": "Article body",
        "tags": [ "tag1", "tag2" ]
    }

/articles/0
    GET: {
        "title": "Why Should I Care About HATEOAS?",
        "body": "Blah blah blah"
        "tags": [ "REST", "HATEOAS" ],
        "_links": {
            "self": { "href": "http://myapi.com/articles/0", "title": "article" },
            "parent": { "href": "http://myapi.com/articles", "title": "articles" }
        }
    }

HATEOAS diklaim memberikan dua manfaat utama:

  1. Seluruh layanan dapat ditemukan mulai dari root URI, dokumentasi tidak lagi diperlukan.

  2. Klien dipisahkan dari server yang sekarang dapat mengubah struktur URI dengan bebas. Ini menghilangkan kebutuhan untuk versi API.

Tetapi dalam pandangan saya, layanan jauh lebih banyak daripada struktur URI-nya. Untuk menggunakannya secara efektif, Anda juga perlu tahu:

  • parameter kueri apa yang dapat Anda gunakan dan nilainya yang mungkin
  • struktur JSON / XML / dokumen apa pun yang perlu Anda kirim dalam permintaan POST / PATCH / etc Anda
  • struktur respons yang dikirim oleh server
  • kemungkinan kesalahan yang mungkin terjadi
  • ...

Berdasarkan hal di atas, HATEOAS hanya memecahkan sebagian kecil dari kemampuan penemuan dan penggandengan. Anda masih perlu mendokumentasikan empat aspek di atas dan klien masih akan sangat digabungkan ke server karena itu. Untuk menghindari kerusakan klien, Anda masih perlu membuat versi API Anda.

Satu-satunya manfaat yang diberikannya adalah Anda dapat mengubah struktur URL Anda lebih atau kurang secara bebas (ngomong-ngomong, apa yang terjadi pada prinsip "Cool URIs not change" ?). Apakah pemahaman saya benar?

Botond Balázs
sumber

Jawaban:

47

Saya pikir insting Anda sebagian besar benar; manfaat yang dicanangkan itu sebenarnya tidak terlalu bagus, karena untuk aplikasi web non-sepele apa pun klien harus peduli tentang semantik dari apa yang mereka lakukan serta sintaksisnya.

Tetapi itu tidak berarti bahwa Anda tidak harus membuat aplikasi Anda mengikuti prinsip-prinsip HATEOAS!

Apa HATEOAS benar-benar berarti? Ini berarti menyusun aplikasi Anda sehingga pada prinsipnya seperti situs web , dan bahwa semua operasi yang mungkin ingin Anda lakukan dapat ditemukan tanpa harus mengunduh beberapa skema rumit. (Skema WSDL yang canggih dapat mencakup segalanya, tetapi pada saat mereka melakukannya, mereka telah melampaui kemampuan hampir setiap programmer untuk memahaminya, apalagi menulis! Anda dapat melihat HATEOAS sebagai reaksi terhadap kompleksitas tersebut.)

HATEOAS tidak hanya berarti tautan kaya. Ini berarti menggunakan mekanisme kesalahan standar HTTP untuk menunjukkan lebih tepatnya apa yang salah; Anda tidak perlu hanya menanggapi dengan "waaah! tidak ”dan sebaliknya dapat memberikan dokumen yang menjelaskan apa yang sebenarnya salah dan apa yang mungkin dilakukan klien tentang hal itu. Ini juga berarti mendukung hal-hal seperti permintaan OPSI (cara standar yang memungkinkan klien untuk mengetahui metode HTTP apa yang dapat mereka gunakan) dan negosiasi jenis konten sehingga format respons dapat disesuaikan dengan bentuk yang dapat ditangani oleh klien. Itu berarti memasukkan teks penjelasan(atau, lebih mungkin, tautan ke sana) sehingga klien dapat mencari cara menggunakan sistem dalam kasus non-sepele jika mereka tidak tahu; teks penjelas mungkin dapat dibaca manusia atau bisa dibaca oleh mesin (dan bisa serumit yang Anda inginkan). Akhirnya, itu berarti bahwa klien tidak mensintesis tautan (kecuali untuk parameter kueri); klien hanya akan menggunakan tautan jika Anda memberi tahu mereka.

Anda harus berpikir tentang memiliki situs yang diramban oleh pengguna (yang dapat membaca JSON atau XML alih-alih HTML, jadi sedikit aneh) dengan memori yang bagus untuk tautan dan pengetahuan ensiklopedi dari standar HTTP, tetapi sebaliknya tidak ada pengetahuan tentang apa yang harus dilakukan. melakukan.

Dan tentu saja, Anda dapat menggunakan negosiasi jenis konten untuk melayani klien HTML (5) / JS yang akan membiarkan mereka menggunakan aplikasi Anda, jika itu yang browser mereka siap untuk terima. Lagi pula, jika RESTful API Anda ada gunanya, itu harus "sepele" untuk diterapkan di atasnya?

Donal Fellows
sumber
6

Masalahnya, HATEOAS harus datang dengan pilar kedua yang menentukan apa itu RESTful API: jenis media terstandarisasi. Kata Roy menerjunkan dirinya sendiri

API REST harus menghabiskan hampir semua upaya deskriptif dalam mendefinisikan jenis media yang digunakan untuk mewakili sumber daya ".

Dengan jenis media terstandarisasi yang mendefinisikan transisi secara eksplisit, dan hypertext untuk menunjuk sumber daya satu sama lain, Anda dapat membuat grafik sumber daya yang dapat berbentuk apa pun tanpa menghancurkan klien mana pun. Seperti pekerjaan web, sungguh: Anda memiliki tautan antara dokumen, dan dokumen ditulis dalam HTML yang menentukan cara mengikuti tautan tersebut. <a href>adalah GET, <form>adalah GET atau POST (dan mendefinisikan templat url untuk digunakan jika GET), <link type="text/css">adalah GET ... dll. Ini adalah bagaimana browser dapat menavigasi halaman HTML terstruktur yang sewenang-wenang dan Web.

Semua poin yang Anda buat

  • parameter kueri apa yang dapat Anda gunakan dan nilainya yang mungkin
  • struktur JSON / XML / dokumen apa pun yang perlu Anda kirim dalam permintaan POST / PATCH / etc Anda
  • struktur respons yang dikirim oleh server
  • kemungkinan kesalahan yang mungkin terjadi

Apakah poin yang harus dikagumi oleh definisi Anda jenis media standar . Tentu saja, ini jauh lebih sulit, dan bukan sesuatu yang kebanyakan orang pikirkan ketika mereka mendefinisikan API "REST". Anda tidak bisa begitu saja membawa Anda entitas bisnis dan mendorong atribut mereka ke dalam dokumen JSON untuk memiliki API yang tenang.

Tentu saja, apa yang terjadi adalah REST entah bagaimana terdilusi menjadi "menggunakan HTTP alih-alih SOAPy thingy yang rumit". Hanya menggunakan HTTP dan HyperText tidak cukup untuk TETAP, ini adalah kesalahan kebanyakan orang.

Bukan berarti ini hal yang buruk: REST membuat pengorbanan kinerja dan kemudahan pengembangan dengan imbalan pemeliharaan yang lebih lama dan evolutivitas. Itu dibuat untuk integrasi aplikasi perusahaan besar. API web kecil dengan struktur JSON berkode keras mungkin sesuai dengan yang Anda butuhkan. Hanya saja jangan menyebutnya REST, ini adalah API web ad-hoc, tidak lebih. Dan itu tidak berarti itu payah, itu hanya berarti itu tidak mencoba untuk mengikuti batasan REST.

Bacaan lebih lanjut

Semoga ini bisa membantu sedikit memperjelas :)

Laurent Bourgault-Roy
sumber
2

Ada beberapa format Hypermedia yang berupaya memberikan respons yang lebih kaya yang mencakup lebih banyak informasi tentang jenis permintaan yang akan dikirim, dan tidak ada yang menghentikan Anda untuk memperkaya respons dengan lebih banyak informasi.

Berikut ini contoh dokumen Siren :

{
  "class": [ "order" ],
  "properties": { 
      "orderNumber": 42, 
      "itemCount": 3,
      "status": "pending"
  },
  "entities": [
    {
      "class": [ "info", "customer" ],
      "rel": [ "http://x.io/rels/customer" ], 
      "properties": { 
        "customerId": "pj123",
        "name": "Peter Joseph"
      },
      "links": [
        { "rel": [ "self" ], "href": "http://api.x.io/customers/pj123" }
      ]
    }
  ],
  "actions": [
    {
      "name": "add-item",
      "title": "Add Item",
      "method": "POST",
      "href": "http://api.x.io/orders/42/items",
      "type": "application/x-www-form-urlencoded",
      "fields": [
        { "name": "orderNumber", "type": "hidden", "value": "42" },
        { "name": "productCode", "type": "text" },
        { "name": "quantity", "type": "number" }
      ]
    }
  ],
  "links": [
    { "rel": [ "self" ], "href": "http://api.x.io/orders/42" },
    { "rel": [ "previous" ], "href": "http://api.x.io/orders/41" },
    { "rel": [ "next" ], "href": "http://api.x.io/orders/43" }
  ]
}

Seperti yang Anda lihat, informasi tentang cara menelepon terkait actionsdisediakan dalam pesan, dan kemudian dengan menafsirkan informasi ini, klien menjadi lebih tahan terhadap perubahan.

Ini menjadi sangat kuat jika rels adalah URI yang dapat dilihat, bukan dari kosa kata yang tetap.

mcintyre321
sumber
0

Di mana Anda membaca bahwa "dokumentasi tidak lagi diperlukan" untuk layanan HATEAOS? Seperti yang Anda katakan, Anda masih perlu mendokumentasikan semantik tautan. Namun, dengan HATEOAS Anda tidak perlu mendokumentasikan, dan karenanya menyimpan selamanya, struktur sebagian besar URI.

HATEOAS memungkinkan pelaksana layanan untuk memodifikasi dan skala implementasi secara signifikan dan efisien tanpa mengubah set kecil URI di mana klien bergantung. Lebih mudah untuk mempertahankan sejumlah kecil titik masuk tidak berubah dari set besar. Oleh karena itu, mengurangi jumlah titik masuk publik ke layanan dan secara dinamis menyediakan tautan ke sub-sumber daya (HATEOAS) sebenarnya mendukung "URI keren tidak berubah" lebih baik daripada layanan non-HATEOAS.

Jonathan Giddy
sumber
Satu tempat di mana orang dapat membaca bahwa "dokumentasi tidak lagi diperlukan" adalah disertasi Roy Fielding, yang menciptakan istilah itu.
meriton - saat mogok
1
Saya baru saja mencari disertasi Fielding untuk penggunaan "dokumentasi" dan tidak menemukan yang menyerupai pernyataan "dokumentasi tidak lagi diperlukan". Bisakah Anda menunjukkan di mana dalam disertasi Fielding Anda menemukan klaim ini?
Jonathan Giddy
0

(HATEOAS), kendala yang diklaim membuat API web "benar-benar tenang"

Satu-satunya hal yang menjadikannya REST API sejati adalah memenuhi semua kendala, bukan hanya satu.

Tetapi dalam pandangan saya, layanan jauh lebih banyak daripada struktur URI-nya. Untuk menggunakannya secara efektif, Anda juga perlu tahu: ...

Itu sebabnya kita membutuhkan kendala lain, pesan deskriptif diri, dll ...

Untuk menghindari kerusakan klien, Anda masih perlu membuat versi API Anda.

Tidak peduli bagaimana Anda mencoba, Anda harus membuat versi API Anda. Di klien REST Anda masih perlu tahu cara menuju ke halaman di mana Anda ingin melakukan hal-hal, tautan mana yang harus diikuti dan properti mana yang perlu Anda kumpulkan berdasarkan pada kosakata RDF yang menjelaskan pesan tersebut. Jika Anda perlu mengganti atau menghapus sesuatu dari vocab itu, maka itu mungkin akan menghancurkan semua klien Anda dan Anda akan memerlukan versi baru. Jadi saya pikir REST bukan sesuatu yang harus Anda publikasikan lebih awal (dan cari tahu modelnya saat Anda terus-menerus mengubah API), jika tidak Anda akan memiliki banyak versi. Anda memerlukan model domain yang stabil terlebih dahulu yang dapat Anda ...

inf3rno
sumber