Apa cara idiomatis untuk menangani versi api [ditutup]

Saya membuat server di Go yang ditujukan untuk aplikasi seluler. Saya harus dapat mendukung beberapa versi API jika pengguna tidak memperbarui aplikasi. Perhatian utama dalam pembuatan versi adalah mengembalikan data dalam format yang benar untuk versi aplikasi seluler.

Saya telah melihat bahwa ada tiga cara dasar untuk melakukan hal ini.
A. Salah satu caranya adalah dengan memiliki satu pengendali rute di /, dan kemudian mengizinkan fungsi tersebut untuk mengurai url untuk pembuatan versi.
Contoh:

func main() {
http.HandleFunc("/", routes.ParseFullURI)
}

B. Gunakan perpustakaan seperti gorilla/mux untuk menangani pola di dalam router, tapi saya melihat beberapa peringatan bahwa ini mungkin terlalu lambat.
Contoh:

  func main() {
            mux.HandleFunc("{version:}/", routes.ParseVersionForHome)
            mux.HandleFunc("{version:}/getData", routes.ParseVersionForGetDAta)
            mux.HandleFunc("{version:}/otherCall", routes.ParseVersionForOtherCall)
            }

C. Memiliki url individual yang tidak berubah, tetapi berdasarkan header, dibagi menjadi beberapa versi. Contoh:

func main() {
   http.HandleFunc("/", routes.ParseHeaderForVersionForHome)
   http.HandleFunc("/getData", routes.ParseHeaderForVersionForGetData)
   http.HandleFunc("/otherCall", routes.ParseHeaderForVersionForOtherCall)
}

Saya khawatir opsi 1 akan menjadi kode yang terlalu berantakan. Saya khawatir opsi 2 akan memiliki kinerja yang terlalu lambat, dan saya khawatir opsi 3 akan sulit ditangani oleh klien, atau akan membingungkan karena versinya tidak diberi label dengan jelas.

Metode manakah yang paling idiomatis untuk Go, dan akan menghasilkan performa terbaik untuk aplikasi seluler yang akan sering disurvei?


person Avik    schedule 21.04.2015    source sumber
comment
Jika Anda berbicara tentang API melalui HTTP(S) maka sesuatu seperti http://example.com/api/v1/… adalah hal yang umum. Atau apakah Anda lebih bertanya bagaimana menerapkan pola seperti itu di server Go?   -  person Dave C    schedule 21.04.2015
comment
Saya bertanya bagaimana cara melakukannya di Go Server. Saya akan menjelaskan lebih lanjut dalam pertanyaan saya.   -  person Avik    schedule 21.04.2015
comment
1 dan 2 pada dasarnya setara, Anda hanya melakukan perutean sendiri terlebih dahulu. Jika gorilla/mux terlalu lambat, jangan gunakan (bahkan HandleFunc default menggunakan router: http.ServeMux). 3 tidak ada hubungannya dengan Go, hanya saja apakah Anda ingin membuat klien Anda menggunakan header atau tidak (yang seharusnya tidak menjadi masalah besar)   -  person JimB    schedule 21.04.2015
comment
Ya, 3 ada hubungannya dengan Go karena dengan jelas mendefinisikan kemungkinan rute di kelas, bukan dalam implementasi fungsi. Yaitu. di mana Anda melihat daftar api yang didukung. Saya akan memperjelasnya melalui contoh.   -  person Avik    schedule 21.04.2015
comment
Banyak router yang memungkinkan pengelompokan rute yang berbeda. Anda mungkin ingin memeriksanya.   -  person placeybordeaux    schedule 21.04.2015
comment
@placeybordeaux Terima kasih. Itu membawa saya ke ini: stackoverflow.com/questions/25298646/ Mungkin arah yang tepat. Apakah Anda ingin mengubahnya menjadi jawaban lengkap? Perlu melihat apakah goji memiliki tolok ukur.   -  person Avik    schedule 21.04.2015
comment
Jangan khawatir tentang kecepatan router. Di https://github.com/julienschmidt/go-http-routing-benchmark Anda melihat timing (untuk rute tolok ukur permintaan tunggal) dalam ribuan nanodetik, seperti dalam mikrodetik, seperti dalam seperseribu milidetik. Biayanya sangat kecil dibandingkan dengan, katakanlah, penulisan database sehingga sulit bagi saya untuk memahaminya secara intuitif.   -  person twotwotwo    schedule 21.04.2015
comment
(Untuk lebih jelasnya, menurut saya echo adalah pencapaian yang bagus! Keren melihat komponen non-alokasi yang tidak sepele. Namun saya tidak ingin siapa pun merasa mereka harus menggunakannya untuk mendapatkan kinerja API yang baik.)   -  person twotwotwo    schedule 21.04.2015
comment
@twotwotwo Saya akan menggunakan redis sebagai database, jadi saya perlu memastikan bahwa penguraian url bukanlah hambatannya.   -  person Avik    schedule 21.04.2015
comment
@Avik Ini benar-benar tidak akan terjadi. Berbicara dengan Redis akan jauh lebih lambat (satu digit hingga puluhan milidetik) dibandingkan rute Anda. Bahkan dengan lebih dari 5.000 rute, router Anda tidak akan bisa mendekati itu. Perhatikan juga bahwa Echo memang mengalokasikan - ini menciptakan kumpulan. Menggunakan kumpulan (get/put) tidak diperhitungkan dalam keluaran alokasi benchmark.   -  person elithrar    schedule 22.04.2015
comment
@elithrar Saya bingung sekarang. Redis melakukan sekitar 72 permintaan per milidetik. Echo diukur pada 4,5 milidetik per permintaan berbasis variabel? Apakah saya salah membaca angkanya?   -  person Avik    schedule 22.04.2015


Jawaban (1)


Ada banyak kerangka perutean yang memungkinkan pengelompokan, misalnya dengan echo (kerangka kerja yang sangat bagus jika Anda menginginkan kecepatan)

package main

import "github.com/labstack/echo"

func ping(c *echo.Context) {
        c.String(200, "pong")
}

func main() {
        e := echo.New()

        v1 := e.Group("/v1")
        v1.Get("/ping", ping)

        v2 := e.Group("/v2")
        v2.Get("/ping", ping)

        e.Run(":4444")
}

Menurutku ini cukup bersih.

Saya yakin banyak kerangka kerja lain yang memungkinkan hal ini. Saya tahu pasti martini melakukannya, tapi itu bukan kerangka idiomatis...

person placeybordeaux    schedule 21.04.2015
comment
Terima kasih. Sekarang saya hanya perlu menemukan perpustakaan terbaik untuk kebutuhan saya, tetapi ini tampaknya merupakan pendekatan paling umum untuk pembuatan versi di Go. Daftar perpustakaan yang mendukung pengelompokan dan cepat sepertinya hampir tidak ada habisnya! - person Avik; 21.04.2015
comment
Hai, Saya telah mencari di internet, dan kesulitan memahami apakah ping memiliki fungsi yang sama, dan jika demikian, bagaimana saya membedakan grup mana yang memanggilnya untuk memberikan hasil yang berbeda. - person Avik; 26.04.2015
comment
Ping fungsinya sama. Dari konteks ping Anda bisa mencari URL yang diberikan. Saya berasumsi bahwa Anda akan memanggil fungsi berbeda untuk versi berbeda. - person placeybordeaux; 30.04.2015