راهاندازی پروژه
- یک دایرکتوری پروژه جدید ایجاد کنید.
- محتویات food_menu.proto money.proto localized_text.proto را از تعاریف proto به عنوان فایلهای جدید در دایرکتوری ریشه پروژه خود کپی کنید.
- کامپایلر protoc را نصب کنید
برای تولید کد منبع از فایلهای .proto، به کامپایلر protoc نیاز دارید. آخرین نسخه باینری از پیش ساخته شده را از صفحه انتشار Protocol Buffers GitHub دانلود کنید.
فایل زیپ را از حالت فشرده خارج کنید و مسیر bin را به متغیر محیطی PATH اضافه کنید، برای مثال:
unzip protoc-22.0-linux-x86_64.zip -d /usr/local/protoc export PATH="$PATH:/usr/local/protoc/bin"
تولید کد منبع
پایتون
- کتابخانه پایتون protobuf را نصب کنید
pip install protobuf
- تولید کد منبع کلاینت.
دایرکتوری خروجی پروتو را ایجاد کنید: generated
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)
مثال کد نشان میدهد که چگونه میتوان یک شیء feed با یکی از هر یک از موجودیتهای زیر ایجاد کرد:
- منو
- بخش منو
- آیتم منو
- گزینه آیتم منو
سپس این مثال نحوه سریالایز کردن فید به JSON را نشان میدهد.
API پایتون با تنظیم ویژگیها، امکان مقداردهی اولیهی تنبل (lazy initialization) اشیاء تودرتو را فراهم میکند.تایپ اسکریپت
- افزونه TypeScript protoc را نصب کنید.
توجه داشته باشید که ts-proto یک پروژه رسمی پشتیبانی شده توسط گوگل نیست.npm init npm i -D typescript npm i ts-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));
مثال کد نشان میدهد که چگونه میتوان یک شیء feed با یکی از هر یک از موجودیتهای زیر ایجاد کرد:
- منو
- بخش منو
- آیتم منو
- گزینه آیتم منو
سپس این مثال نحوه سریالایز کردن فید به JSON را نشان میدهد.
جاوا
- وابستگیهای 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); } }
مثال کد نشان میدهد که چگونه میتوان یک شیء feed با یکی از هر یک از موجودیتهای زیر ایجاد کرد:
- منو
- بخش منو
- آیتم منو
- گزینه آیتم منو
سپس این مثال نحوه سریالایز کردن فید به 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)) }
مثال کد نشان میدهد که چگونه میتوان یک شیء feed با یکی از هر یک از موجودیتهای زیر ایجاد کرد:
- منو
- بخش منو
- آیتم منو
- گزینه آیتم منو
سپس این مثال نحوه سریالایز کردن فید به JSON را نشان میدهد.