إعداد المشروع
- أنشئ دليل مشروع جديدًا.
- انسخ محتوى food_menu.proto money.proto localized_text.proto من تعريفات proto كملفات جديدة إلى الدليل الجذري لمشروعك.
- تثبيت مُجمِّع protoc
لإنشاء رمز المصدر من ملفات .proto، ستحتاج إلى برنامج تجميع protoc. نزِّل أحدث ملف ثنائي مُعدّ مسبقًا من صفحة الإصدار الخاصة بـ Protocol Buffers على GitHub.
استخرِج ملف zip وأضِف مسار bin إلى متغيّر البيئة PATH، على سبيل المثال:
unzip protoc-22.0-linux-x86_64.zip -d /usr/local/protoc export PATH="$PATH:/usr/local/protoc/bin"
إنشاء رمز المصدر
Python
- تثبيت مكتبة protobuf في Python
pip install protobuf
- أنشئ رمز المصدر الخاص بالعميل.
أنشئ دليل إخراج proto: تم إنشاؤه.
protoc --python_out=./generated food_menu.proto money.proto localized_text.proto
عدِّل متغيّر البيئة PYTHONPATH لتضمين المسار الذي تم إنشاؤه، على سبيل المثال:
export PYTHONPATH="$PYTHONPATH:./generated"
إذا كنت تستخدم Bazel، جرِّب قاعدة py_proto_library كبديل لتشغيل protoc.
مثال على الاستخدام
يمكنك الاطّلاع على مثال المشروع الكامل هنا.
"""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 message 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)
يوضّح مثال الرمز البرمجي كيفية إنشاء عنصر خلاصة يتضمّن واحدًا من كلّ من العناصر التالية:
- القائمة
- MenuSection
- MenuItem
- MenuItemOption
يوضّح المثال بعد ذلك كيفية تسلسل الخلاصة إلى تنسيق JSON.
تسمح واجهة برمجة التطبيقات Python ببدء تشغيل الكائنات المُدمجة بشكلٍ غير فوري من خلال ضبط السمات.TypeScript
-
ثبِّت المكوّن الإضافي TypeScript protoc.
يُرجى العِلم أنّ ts-proto ليس مشروعًا رسميًا تدعمه Google.npm init npm i -D typescript npm i ts-proto
- أنشئ دليل الإخراج وأنشئ رمز المصدر للعميل.
أنشئ دليل الإخراج 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
إذا كنت تستخدم Bazel، جرِّب قاعدة js_proto_library كبديل لتشغيل protoc.
مثال على الاستخدام
يمكنك الاطّلاع على مثال المشروع الكامل هنا.
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://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 (new Blob([JSON.stringify(feed)]).size > 200 * 1024 * 1024) { // create a new file } console.log(JSON.stringify(feed));
يوضّح مثال الرمز البرمجي كيفية إنشاء عنصر خلاصة يتضمّن واحدًا من كلّ من العناصر التالية:
- القائمة
- MenuSection
- MenuItem
- MenuItemOption
يوضّح المثال بعد ذلك كيفية تسلسل الخلاصة إلى تنسيق JSON.
Java
- أضِف التبعيات protobuf-java وprotobuf-java-util إلى مشروعك باستخدام maven أو gradle كما هو موضّح هنا.
- أنشئ رمز المصدر الخاص بالعميل.
protoc --java_out=src/main/java food_menu.proto money.proto localized_text.proto
يمكنك استخدام protobuf-maven-plugin لإنشاء رمز المصدر أثناء وقت التجميع عند استخدام maven.
إذا كنت تستخدم Bazel، جرِّب قاعدة java_proto_library كبديل لتشغيل protoc.
مثال على الاستخدام
يمكنك الاطّلاع على مثال المشروع الكامل هنا.
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 recommended 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); } }
يوضّح مثال الرمز البرمجي كيفية إنشاء عنصر خلاصة يتضمّن واحدًا من كلّ من العناصر التالية:
- القائمة
- MenuSection
- MenuItem
- MenuItemOption
يوضّح المثال بعد ذلك كيفية تسلسل الخلاصة إلى تنسيق JSON.
البدء
- تثبيت المكوّن الإضافي protoc لبرنامج go
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
عدِّل متغيّر البيئة PATH لتضمين المكوّن الإضافي protoc-gen-go، على سبيل المثال:
export PATH="$PATH:$(go env GOPATH)/bin"
- بدء التطبيق وإنشاء رمز المصدر للعميل
go mod init feed/app mkdir generated protoc --go_out=./generated/ food_menu.proto money.proto localized_text.proto
إذا كنت تستخدم Bazel، جرِّب قاعدة go_proto_library كبديل لتشغيل protoc.
مثال على الاستخدام
يمكنك الاطّلاع على مثال المشروع الكامل هنا.
/* 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/protobuf/proto" ) func main() { //create a menu component menu := &pb.Menu{ MenuId: "menu1", MerchantIds: []string{"dining-1"}, DisplayName: &pb.TextField{ Text: []*localized_text.LocalizedText{{ Text: "Menu", LanguageCode: "en-us", }}, }, Language: "en-us", LastMerchantUpdateTime: ×tamppb.Timestamp{ Seconds: 1633621547, }, } //create a menu section component section := &pb.MenuSection{ MenuSectionId: "appetizers", DisplayName: &pb.TextField{ Text: []*localized_text.LocalizedText{{ Text: "Lunch Appetizers", LanguageCode: "en-us", }}, }, MenuItemIds: []string{"breadsticks-sauce"}, } //create a menu item component item := &pb.MenuItem{ MenuItemId: "breadsticks-sauce", DisplayName: &pb.TextField{ Text: []*localized_text.LocalizedText{{ Text: "Breadsticks & Sauce", LanguageCode: "en-us", }}, }, Description: &pb.TextField{ Text: []*localized_text.LocalizedText{{ Text: "Breakfast basket w/ side of tomato sauce (size 6 or 12)", LanguageCode: "en-us", }}, }, Pricing: &pb.MenuItem_MenuItemOptionSet_{ MenuItemOptionSet: &pb.MenuItem_MenuItemOptionSet{ MenuItemOptionIds: []string{"breadstick-sm", "breadstick-lg"}, }, }, } imageUris := []string{ "http://www.example.com/photos/breadsticks.jpg", "http://www.example.com/photos/sauce.jpg", } for _, uri := range imageUris { image := &pb.Image{ Uri: uri, } item.Images = append(item.Images, image) } //create a menu item option option := &pb.MenuItemOption{ MenuItemOptionId: "breadstick-sm", Value: &pb.MenuItemOptionProperty{ PropertyType: pb.MenuItemOptionProperty_SIZE, Value: &pb.MenuItemOptionProperty_TextVal{ TextVal: &pb.TextField{ Text: []*localized_text.LocalizedText{{ Text: "Small", LanguageCode: "en-us", }}, }, }, }, OfferSet: &pb.OfferSet{ Offers: []*pb.Offer{{ Price: &money.Money{ CurrencyCode: "USD", Units: 8, Nanos: 0, }, }}, }, } //create feed feed := &pb.FoodMenuFeed{ Data: []*pb.MenuComponent{{ Type: &pb.MenuComponent_Menu{ Menu: menu, }, }, { Type: &pb.MenuComponent_Section{ Section: section, }, }, { Type: &pb.MenuComponent_Item{ Item: item, }, }, { Type: &pb.MenuComponent_Option{ Option: 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 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)) }
يوضّح مثال الرمز البرمجي كيفية إنشاء عنصر خلاصة يتضمّن واحدًا من كلّ من العناصر التالية:
- القائمة
- MenuSection
- MenuItem
- MenuItemOption
يوضّح المثال بعد ذلك كيفية تسلسل الخلاصة إلى تنسيق JSON.