Konektivitas lemah

NB : Ini adalah draf dua bab baru dari buku saya tentang Desain API. Teks tersebut berisi referensi ke bab-bab sebelumnya.







Konektivitas yang kuat dan masalah terkait



Pada bagian sebelumnya, kami mencoba memberikan aturan dan prinsip teoretis, dan mengilustrasikannya dengan contoh praktis. Namun, memahami prinsip mendesain API yang tahan terhadap perubahan membutuhkan lebih banyak latihan daripada apa pun. Pengetahuan tentang di mana harus "meletakkan jerami" dalam banyak hal adalah "anak kesalahan yang sulit." Anda tidak dapat meramalkan segalanya - tetapi Anda dapat mengembangkan tingkat intuisi teknis yang diperlukan.







Oleh karena itu, di bagian ini, kami akan melanjutkan sebagai berikut: ambil model API kami dari bagian sebelumnya, dan periksa stabilitasnya di setiap titik yang memungkinkan - kami akan melakukan beberapa "analisis variasional" dari antarmuka kami. Lebih khusus lagi, kita akan mendekati setiap entitas dengan pertanyaan "bagaimana jika?" - bagaimana jika kita perlu memberi mitra kemampuan untuk menulis implementasi independen mereka sendiri dari bagian logika ini.







Poin penting pertama yang harus diperhatikan: kita berbicara secara khusus tentang opsi untuk penerapan logika produk . Bukan tentang opsi untuk implementasi entitas : perubahan dalam API dibuat terutama untuk memungkinkan melakukan sesuatu yang tidak disediakan oleh desain asli - sesuatu yang berguna. Pelanggan Anda tidak akan menerapkan ulang antarmuka begitu saja.







Pertimbangan ini memperkenalkan batasan tertentu yang memungkinkan kita untuk tidak membabi buta mengubah antarmuka (lagipula, ada jumlah pilihan yang tak terbatas, dan untuk menyediakan semuanya adalah pekerjaan Sisyphean): kita perlu memahami, pertama-tama, mengapa tertentu perubahan diperlukan, dan dari sini kita sudah memahami bagaimana mereka harus diperkenalkan.







Poin penting kedua adalah banyak solusi yang memungkinkan variasi ini sudah dibangun ke dalam desain API. Kami membahas beberapa di antaranya (misalnya, masalah menentukan kesiapan) secara lebih rinci di bab-bab sebelumnya, dan beberapa memberi tanpa komentar - inilah saatnya menjelaskan mengapa keputusan ini dibuat.







NB: , ; ad hoc , . API ; , , .







, . ?







  • , «» ;
  • , .


. , ? , «»: , . , :







//   
POST /v1/recipes
{
  "id",
  "product_properties": {
    "name",
    "description",
    "default_value"
    //  , 
    //   
  },
  "execution_properties": {
    //  
    "program_id",
    //   
    "parameters"
  }
}
      
      





, , . , — .







, 11: . :







"product_properties": {
  // "l10n" —  
  //  "localization"
  "l10n" : [{
    "language_code": "en", 
    "country_code": "US", 
    "name", 
    "description" 
  }, /*     */ … ]
]
      
      





default_volume



? , , , . , , , «300 », «10 ». :







  • , ;
  • , .


, API - — , API. , — . .







, , API . — name



description



? , . — /v1/search



, : search



?







— , UI . -, name



description



— , ( ) ( ). , API . , UI ? , , : name



— «-» , . -, , UI; -, . , , «», «» «» « » « ».







— UI ( ) , ( , , ). product_properties



, , .







, — . , , , () ( , ). API « », . , : . .









: , . — , (, , .. API) .







, . - , API, — , API . - API :







l10n.volume.format(value, language_code, country_code)
// l10n.formatVolume('300ml', 'en', 'UK') → '300 ml'
// l10n.formatVolume('300ml', 'en', 'US') → '10 fl oz'
      
      





API , , , . , , :







//    
//   
PUT /formatters/volume/ru
{
  "template": "{volume} "
}
//    
//      «»
PUT /formatters/volume/ru/US
{
  //     
  // ,   
  "value_preparation": {
    "action": "divide",
    "divisor": 30
  },
  "template": "{volume} ."
}
      
      





NB: , , , , , (, , ), (.. ). .







name



description



. , , (, , API) «». name



description



, UI. UI .







GET /v1/layouts/{layout_id}
{
  "id",
  //      ,
  //     
  // 
  "kind": "recipe_search",
  //    ,
  //     
  //   
  "properties": [{
    //    ,  `name`
    //      
    //     —
    //      `seach_title`
    "field": "search_title",
    "view": {
      //   ,
      //    
      "min_length": "5em",
      "max_length": "20em",
      "overflow": "ellipsis"
    }
  }, …],
  //   
  "required": ["search_title", "search_description"]
}
      
      





, , . :







PUT /v1/recipes/{id}/properties/l10n/{lang}
{
  "search_title", "search_description"
}
      
      





:







POST /v1/layouts
{
  "properties"
}
{ "id", "properties" }
      
      





, UI , , .







— , — execution_properties



, , . :







POST /v1/recipes
{ "id" }
{ "id" }
      
      





, «» , . , , -, :







POST /v1/recipe-builder
{
  "id",
  //   
  "product_properties": {
    "default_volume",
    "l10n"
  },
  //  
  "execution_properties"
  //   
  "layouts": [{
    "id", "kind", "properties"
  }],
  //   
  "formatters": {
    "volume": [
      { "language_code", "template" },
      { "language_code", "country_code", "template" }
    ]
  },
  //  ,  
  //    
  //    
}
      
      





, — . , — , , - . , , , , : ( ), , 11.







POST /v1/recipes/custom
{
  //   :
  // ,    
  "namespace": "my-coffee-company",
  //   
  "id_component": "lungo-customato"
}
{
  "id": "my-coffee-company:lungo-customato"
}
      
      





, : , . , "common", . (, , , API .)









, . , API 9 «» « ». , program-matcher



:







GET /v1/recipes/{id}/run-data/{api_type}
{ /*   
       
        
       API */ }
      
      





:







  • API -;
  • API ;
  • API .


, — , , API -. , «», , «».







program_run_id



, . .







, , . API - API. , , -, API. API , - ?







, API : , () . API — , :







//   
// - 
PUT /partners/{id}/coffee-machines
{
  "coffee-machines": [{
    "id",
    "program_api": {
      "program_run_endpoint": {
        /* - 
              */
        "type": "rpc",
        "endpoint": <URL>,
        "format"
      },
      "program_state_endpoint",
      "program_stop_endpoint"
    }
  }, …]
}
      
      





NB: API ( program_run_endpoint



, program_state_endpoint



, .)







API , , API . .







  1. (.. API), : , .
  2. : .


2 , 1. , , — , , . , , program_modify_endpoint



, ( , ). , , ( , ) .







- , . : , API , . , , , modify



API — , . , , , : , - , « ». , , , , , , , , , , , .







, , program_takeout_endpoint



. :







  • program_takeout_endpoint



    , program_modify_endpoint



    ;
  • program_modify_endpoint



    , program_takeout_endpoint



    .


, . , takeout



. - modify



, . , , — API , .







, API , . , , «» , , : , API -, . — , , — , , .







, . API « », .







? : , . ? - :







  • API , ; , : - - , , - ;
  • API , API ; , .


, , , : , . , « ».







:







  • , ;
  • : , .


, , (- ) . SDK :







/*   
       - */
registerProgramRunHandler(apiType, (program) => {
  //   
  //    
  let execution = initExecution(…);
  //   
  //  
  program.context.on('takeout_requested', () => {
    //    ,
    //  
    execution.prepareTakeout(() => {
        //      ,
        //   
        execution.context.emit('takeout_ready');
    });
  });

  return execution.context;
});
      
      





NB: HTTP API , GET /program-run/events



GET /partner/{id}/execution/events



, . , Apache Kafka Amazon SQS.







, , , , :







  • takeout



    takeout_requested



    /takeout_ready



    ;
  • , API , context



    , ;
  • , .


. API , . API : . ? , ; - ( !) , ( ).







, . , :







  • , API — ; , , ;
  • — , , , .


, — , - .







, , (, ) API, , . program



( , , ); execution



( , , API). , execution



- , - API, program



- , .







, . API, , , , . , UI. , SDK.









, , . , — . :







/*   
       - */
registerProgramRunHandler(apiType, (program) => {
  //   
  //    
  let execution = initExection(…);
  //   
  //  
  program.context.on('takeout_requested', () => {
    //    ,
    //  
    execution.prepareTakeout(() => {
      /*      ,
            ,  
             */
      // execution.context.emit('takeout_ready')
      program.context.set('takeout_ready');
      //    :
      // program.setTakeoutReady();
    });
  });
  //       
  //   - 
  // return execution.context;
}
      
      





, . : , . , , , , . .







, , , :







  • , , — ;
  • , , API . API , .


, API API , «» «-».







NB: . , — Redux. Redux :







execution.prepareTakeout(() => {
  //     
  //     ,
  //    
  //      
  dispatch(takeoutReady());
});
      
      





, , — , API, . ( -) , , : , , .







execution.prepareTakeout(() => {
  //     
  //     ,
  //    
  // 
  program.context.dispatch(takeoutReady());
});
      
      





//  program.context.dispatch
ProgramContext.dispatch = (action) => {
  // program.context   
  //  ,   
  // ,    
  globalContext.dispatch(
    //     
    //     
    //    
    // 
    this.generateAction(action);
  )
}
      
      








Ini adalah draf dua bab baru di bagian Kompatibilitas Mundur yang akan datang dari buku saya tentang pengembangan API. Pekerjaan dilakukan di Github . Versi bahasa Inggris dari bab yang sama diterbitkan pada medium . Saya akan berterima kasih jika Anda dapat membagikannya di reddit - Saya sendiri tidak dapat sesuai dengan kebijakan platform.








All Articles