Configura el proyecto
- Crea un directorio de proyecto nuevo.
- Copia el contenido de food_menu.proto money.proto localized_text.proto de las definiciones de proto como archivos nuevos en la raíz del directorio de tu proyecto.
- Instala el compilador de protoc
Para generar código fuente a partir de los archivos .proto, necesitarás el compilador de protoc. Descarga el objeto binario precompilado más reciente de la página de versiones de Protocol Buffers en GitHub.
Extrae el archivo zip y agrega la ruta de acceso bin a la variable de entorno PATH; por ejemplo:
unzip protoc-22.0-linux-x86_64.zip -d /usr/local/protoc export PATH="$PATH:/usr/local/protoc/bin"
Genera código fuente
Python
- Instala la biblioteca de protobuf de Python
pip install protobuf
- Genera código fuente del cliente.
Crea el directorio de salida de proto: generated
protoc --python_out=./generated food_menu.proto money.proto localized_text.proto
Actualiza la variable de entorno PYTHONPATH para incluir la ruta de acceso generada; por ejemplo:
export PYTHONPATH="$PYTHONPATH:./generated"
Si usas Bazel, prueba la regla py_proto_library como alternativa a la ejecución de protoc.
Ejemplo de uso
Puedes encontrar el proyecto de ejemplo completo aquí.
"""Menu feed example used in https://developers.google.com/maps-booking/verticals/dining/guides/tutorials/tutorial-menu-feed-protos#python. """ import json from generated import food_menu_pb2 from google.protobuf.json_format import MessageToDict # create feed feed = food_menu_pb2.FoodMenuFeed() # add a menu component to feed data menuComponent = feed.data.add() menuComponent.menu.menu_id = 'menu1' menuComponent.menu.merchant_ids.append('dining-1') menuDisplayName = menuComponent.menu.display_name.text.add() menuDisplayName.text = 'Menu' menuDisplayName.language_code = 'en-us' menuComponent.menu.language = 'en-us' menuComponent.menu.last_merchant_update_time.seconds = 1633621547 for i in ['appetizers', 'dinner']: menuComponent.menu.menu_section_ids.append(i) # add a menu section component to feed data sectionComponent = feed.data.add() sectionComponent.section.menu_section_id = 'appetizers' sectionDisplayName = sectionComponent.section.display_name.text.add() sectionDisplayName.text = 'Lunch Appetizers' sectionDisplayName.language_code = 'en-us' sectionComponent.section.menu_item_ids.append('breadsticks-sauce') # add a menu item component to feed data itemComponent = feed.data.add() itemComponent.item.menu_item_id =& 'breadsticks-sauce' itemDisplayName = itemComponent.item.display_name.text.add() itemDisplayName.text = 'Breadsticks Sauce' itemDisplayName.language_code = 'en-us' itemDescription = itemComponent.item.description.text.add() itemDescription.text = 'Breakfast basket w/ side of tomato sauce (size 6 or 12)' itemDescription.language_code = 'en-us' for i in ['breadstick-sm', 'breadstick-lg']: itemComponent.item.menu_item_option_set.menu_item_option_ids.append(i) for i in [ 'http://www.example.com/photos/breadsticks.jpg', 'http://www.example.com/photos/sauce.jpg', ]: itemImage = itemComponent.item.images.add() itemImage.uri = i # add a menu item option component to feed data optionComponent = feed.data.add() optionComponent.option.menu_item_option_id: 'breadstick-sm' optionComponent.option.value.property_type = ( food_menu_pb2.MenuItemOptionProperty.PropertyType.SIZE ) optionTextValue = optionComponent.option.value.text_val.text.add() optionTextValue.text = 'Small' optionTextValue.language_code = 'en-us' optionOffer = optionComponent.option.offer_set.offers.add() optionOffer.price.currency_code = 'USD' optionOffer.price.units = 8 optionOffer.price.nanos = 0 # Example testing for menu feed size # Protocol buffer mes>sage must be less than 2 GiB # https://protobuf.dev/programming-guides/proto-limits/ # It is recommended to not exceed 200 MB, as there is an Actions # Center limit of 200 MB per file after compression. if feed.ByteSize() 200 * 1024 * 1024: # start new file print('starting new file...') feedJSON = json.dumps(MessageToDict(feed, preserving_proto_field_name=True)) print(feedJSON)
En el ejemplo de código, se muestra cómo crear un objeto de feed con una de cada una de las siguientes entidades:
- Menú
- MenuSection
- MenuItem
- MenuItemOption
Luego, en el ejemplo, se muestra cómo serializar el feed a JSON.
La API de Python permite la inicialización diferida de objetos anidados mediante la configuración de las propiedades.TypeScript
-
Instala el complemento de protoc de TypeScript.
Ten en cuenta que ts-proto no es un proyecto de Google admitido oficialmente.npm init npm i -D typescript npm i ts-proto
- Crea el directorio de salida y genera código fuente del cliente.
Crea el directorio de salida de proto: src/generated
protoc --plugin="./node_modules/.bin/protoc-gen-ts_proto" --ts_proto_opt=useOptionals=all --ts_proto_opt=snakeToCamel=false --ts_proto_opt=onlyTypes=true --ts_proto_out="./src/generated" food_menu.proto money.proto localized_text.proto
Si usas Bazel, prueba la regla js_proto_library como alternativa a la ejecución de protoc.
Ejemplo de uso
Puedes encontrar el proyecto de ejemplo completo aquí.
import {FoodMenuFeed, Menu, MenuItem, MenuSection, MenuItemOption, MenuItemOptionProperty_PropertyType} from './generated/food_menu'; const menu: Menu = { menu_id: 'menu1', merchant_ids: ['dining-1'], display_name: {text: [{text: 'Menu', language_code: 'en-us'}]}, language: 'en-us', menu_section_ids: ['appetizers', 'dinner'], last_merchant_update_time: new Date() }; const section: MenuSection = { menu_section_id: 'appetizers', display_name: {text: [{text: 'Lunch Appetizers', language_code: 'en-us'}]}, menu_section_ids: ['breadsticks-sauce'] }; const item&: MenuItem = { menu_item_id: 'breadsticks-sauce', display_name: {text: [{text: 'Breadsticks Sauce', language_code: 'en-us'}]}, description: { text: [{ text: 'Breakfast basket w/ side of tomato sauce (size 6 or 12)', language_code: 'en-us' }] }, menu_item_option_set: {menu_item_option_ids: ['breadstick-sm', 'breadstick-lg']}, images: [ {uri: 'http://www.example.com/photos/breadsticks.jpg'}, {uri: 'http://www.example.com/photos/sauce.jpg'} ] }; const option: MenuItemOption = { menu_item_option_id: 'breadstick-sm', value: { property_type: MenuItemOptionProperty_PropertyType.SIZE, text_val: { text: [ {text: "Small", language_code: "en-us"} ] } }, offer_set: { offers: [{ price: { currency_code: "USD", units: 8, nanos: 0 } }] } }; const feed: FoodMenuFeed = { data: [{menu}, {section}, {item}, {option}] }; // Example testing for menu feed size // Protocol buffer message must be less than 2 GiB // https://pr>otobuf.dev/programming-guides/proto-limits/ // It is recommended to not exceed 200 MB, as there is an Actions // Center limit of 200 MB per file after compression. if (new Blob([JSON.stringify(feed)]).size 200 * 1024 * 1024) { // create a new file } console.log(JSON.stringify(feed));
En el ejemplo de código, se muestra cómo crear un objeto de feed con una de cada una de las siguientes entidades:
- Menú
- MenuSection
- MenuItem
- MenuItemOption
Luego, en el ejemplo, se muestra cómo serializar el feed a JSON.
Java
- Agrega las dependencias protobuf-java y protobuf-java-util a tu proyecto con Maven o Gradle, como se describe aquí.
- Genera código fuente del cliente.
protoc --java_out=src/main/java food_menu.proto money.proto localized_text.proto
Puedes usar el complemento protobuf-maven-plugin para generar el código fuente durante el tiempo de compilación cuando usas Maven.
Si usas Bazel, prueba la regla java_proto_library como alternativa a la ejecución de protoc.
Ejemplo de uso
Puedes encontrar el proyecto de ejemplo completo aquí.
package com.example; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Timestamp; import com.google.type.Money; import com.google.protobuf.util.JsonFormat; import com.google.type.LocalizedText; import food.menu.v1.FoodMenu.FoodMenuFeed; import food.menu.v1.FoodMenu.Menu; import food.menu.v1.FoodMenu.MenuComponent; import food.menu.v1.FoodMenu.MenuItem; import food.menu.v1.FoodMenu.MenuSection; import food.menu.v1.FoodMenu.TextField; import food.menu.v1.FoodMenu.MenuItemOption; import food.menu.v1.FoodMenu.MenuItemOptionProperty; import food.menu.v1.FoodMenu.OfferSet; import food.menu.v1.FoodMenu.Offer; /** * Menu feed example used in * * <p>https://developers.google.com/maps-booking/verticals/dining/guides/tutorials/tutorial-menu-feed-protos#java. */ public class Feed { // 200 MB public static final int MAX_BYTES_DATA_FILE = 200 * 1024 * 1024; public static void main(String[] args) throws InvalidProtocolBufferException { Feed feed = new Feed(); feed.createMenuFeed(); } public void createMenuFeed() throws InvalidProtocolBufferException { Menu.Builder menu = Menu.newBuilder() .setMenuId("menu1") .addMerchantIds("dining-1") .setDisplayName( TextField.newBuilder() .addText(LocalizedText.newBuilder().setText("Menu").setLanguageCode("en-us"))) .setLanguage("en-us") .setLastMerchantUpdateTime(Timestamp.newBuilder().setSeconds(1633621547)); MenuSection.Builder section = MenuSection.newBuilder() .setMenuSectionId("appetizers") .setDisplayName( TextField.newBuilder() .addText( LocalizedText.newBuilder() .setText("Lunch Appetizers") .setLanguageCode("en-us"))) .addMenuItemIds("breadsticks-sauce"); MenuItem.Builder item = MenuItem.newBuilder() .setMenuItemId("breadsticks-sauce") .setDisplayName( TextField.newBuilder() .addText( & LocalizedText.newBuilder() .setText("Breadsticks Sauce") .setLanguageCode("en-us"))) .setDescription( TextField.newBuilder() & .addText( LocalizedText.newBuilder() .setText("Breadsticks Sauce") .setLanguageCode("en-us"))); MenuItemOption.Builder option = MenuItemOption.newBuilder() .setMenuItemOptionId("breadstick-sm") .setValue( MenuItemOptionProperty.newBuilder() .setPropertyType(MenuItemOptionProperty.PropertyType.SIZE) .setTextVal(TextField.newBuilder() .addText( LocalizedText.newBuilder() .setText("Small") .setLanguageCode("en-us")))) .setOfferSet( OfferSet.newBuilder() .addOffers( Offer.newBuilder() .setPrice( Money.newBuilder() .setCurrencyCode("USD") .setUnits(8) .setNanos(0)))); FoodMenuFeed.Builder foodMenuFeed = FoodMenuFeed.newBuilder() .addData(MenuComponent.newBuilder().setMenu(menu)) .addData(MenuComponent.newBuilder().setSection(section)) .addData(MenuComponent.newBuilder().setItem(item)) .addData(MenuComponent.newBuilder().setOption(option)); // Example testing for menu feed size // Protocol buffer message must be less than 2 GiB // https://protobuf.dev/programming-guides/proto-limits/ // It is recom>mended to not exceed 200 MB, as there is an Actions // Center limit of 200 MB per file after compression. int size = foodMenuFeed.build().getSerializedSize(); if (size MAX_BYTES_DATA_FILE) { // create new file } String feedJSON = JsonFormat.printer() .omittingInsignificantWhitespace() .preservingProtoFieldNames() .print(foodMenuFeed); System.out.println(feedJSON); } }
En el ejemplo de código, se muestra cómo crear un objeto de feed con una de cada una de las siguientes entidades:
- Menú
- MenuSection
- MenuItem
- MenuItemOption
Luego, en el ejemplo, se muestra cómo serializar el feed a JSON.
Go
- Instala el complemento de protoc para Go
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
Actualiza la variable de entorno PATH para incluir el complemento protoc-gen-go; por ejemplo:
export PATH="$PATH:$(go env GOPATH)/bin"
- Inicializa la app y genera código fuente del cliente.
go mod init feed/app mkdir generated protoc --go_out=./generated/ food_menu.proto money.proto localized_text.proto
Si usas Bazel, prueba la regla go_proto_library como alternativa a la ejecución de protoc.
Ejemplo de uso
Puedes encontrar el proyecto de ejemplo completo aquí.
/* Menu feed example used in https://developers.google.com/maps-booking/verticals/dining/guides/tutorials/tutorial-menu-feed-protos#go. * */ package main import ( pb "feed/app/generated/food/menu/v1/proto" "fmt" localized_text "google.golang.org/genproto/googleapis/type/localized_text" money "google.golang.org/genproto/googleapis/type/money" "google.golang.org/protobuf/encoding/protojson" timestamppb "google.golang.org/protobuf/types/known/timestamppb" proto "google.golang.org/proto&buf/proto" ) func main() { //create a menu component menu := pb.Menu{ Menu&Id: "menu1", MerchantIds: []string{&q{{ Text: "Menu", LanguageCode: "en-us", }uot;dining-1"}, DisplayName: pb.TextField{ Te&xt: []*localized_text.LocalizedText}, }, Language: "en-us", LastMerchantUpdateTime: tim&estamppb.Timestamp{ Seconds: 1633621547, }, } //create& a menu section component section := pb.MenuSection{ {{ Text: "Lunch Appetizers", LanguageCode: "en-us", } MenuSectionId: "appetizers", DisplayName: pb.TextField{ Text: []*localized_text.Lo&calizedText}, }, MenuItemIds: []string{"breadsticks-sa&uce"}, } //create a menu item component item {{ Text: "Breadsticks & Sauce", LanguageCode: "en-us", }:= pb.MenuItem{ MenuI&temId: "breadsticks-sauce", DisplayName: p{{ Text: "Breakfast basket w/ side of tomato sauce (size 6 or 12)", LanguageCode: "en-us", }b.TextField{ Tex&t: []*localized_text.LocalizedText}, }, Descriptio&n: pb.TextField{ Text: []*localized_text.LocalizedText}, }, Pricing: pb.MenuItem_MenuItemOptionSet_{ MenuItemOptionSet: pb.MenuItem_MenuItemOptionSet{ MenuItemOptionIds: []string{"breadstick-sm", "breadstick-lg"}, }, }, } imageUris := []s&tring{ "http://www.example.com/photos/breadsticks.jpg", "http://www.example.com/photos/sauce.jp&g", } for _, uri := range imageUris { image := pb.Image{& Uri: uri, } item.Images = append(item.Images, image) } //create a menu item& option option := pb.MenuItemOption{ MenuItem&OptionId: "breadstick-sm", Value: pb.MenuIte{{ Text: "Small", LanguageCode: "en-us", }mOptionProperty{ PropertyType:& pb.MenuItemOptionProperty_SIZE, {{ Price: &money.Money{ CurrencyCode: "USD", Units: 8, Nanos: 0, }, } Value: pb.MenuItemOptionProperty_Te&xtVal{ TextVal: pb.TextField{ Text:{{ Type: &pb.MenuComponent_Menu{ Menu: menu, }, }, { Type: &pb.MenuComponent_Section{ Section: section, }, }, { Type: &pb.MenuComponent_Item{ Item: item, }, }, { Type: &pb.MenuComponent_Option{ Option: option, }, } []*localized_text.LocalizedText}, }, }, }, OfferSet: pb.OfferSet{ Offers: []*pb.Offer}, }, } //create feed feed := pb.FoodMenuFeed{ Data: []*pb.MenuComponent}, } // Example testing for menu feed size // Protocol buffer message must be less than 2 GiB // https://protobuf.dev/pr>ogramming-guides/proto-limits/ // It is recommended to not exceed 200 MB, as there is an Actions // Center limit of 200 MB per file after compression. if proto.Size(feed) 200 * 1024 * 1024 { // create new file } marshalOptions := protojson.MarshalOptions{ UseProtoNames: true, } jsonBytes, _ := marshalOptions.Marshal(feed) fmt.Printf("message = %s", string(jsonBytes)) }
En el ejemplo de código, se muestra cómo crear un objeto de feed con una de cada una de las siguientes entidades:
- Menú
- MenuSection
- MenuItem
- MenuItemOption
Luego, en el ejemplo, se muestra cómo serializar el feed a JSON.