شاید اکثر ما با ساختار Protocol Buffer و بستر ارتباطی GRPC آشنا باشیم و همواره در پروژه ها با این موارد کار کرده باشیم.
اما پروتکل بافر به چندتا متد RPC و مسیج ختم نمی شود و امکانات دیگری وجود دارد تا بتوانید یکسری سربارهای کدنویسی در پروژه کاهش دهید و یکسری سناریوها را با این امکانات موجود پیاده سازی کنید.
یکی از این امکانات بحث option ها هستش که شما می توانید برای Method, Message و Message Fields پیاده سازی و استفاده کنید.
در این آموزش قصدم دارم به مقوله option برای متدها بپردازم و یک سناریو در خصوص بحث Permission برای متدها توضیح بدم که بتوانید برای متدهاتون یکسری Permission کد تعریف کنید و با توجه به Payload داخل JWT بیاید دسترسی ها را داخل Middleware بررسی کنید.
import "google/protobuf/descriptor.proto"
۳. پس از ایمپورت option مربوط به دسترسی ها را تعریف کنید.
۴. پس از تعریف option آن را برای متد های rpc خود تعریف کنید و مقدار permission را تنظیم کنید که این متد چه دسترسی هایی می تواند داشته باشد.
۵. حال که permission ها را تعریف کردید فایل پروتکل بافر را جنریت کنید به زبان گو.
protoc --proto_path=proto --proto_path=proto/include/googleapis --proto_path=proto/include/grpc-gateway --go-grpc_out=proto/protoModel --go_out=proto/protoModel --grpc-gateway_out=logtostderr=true:proto/protoModel --openapiv2_out=logtostderr=true:api/swagger proto/server/*.proto
۶. اکنون قبل از هرکاری پکیج protoreflect را به ماژول های پروژه تان اضافه کنید.
go get -u github.com/jhump/protoreflect
۷. پس از افزودن ماژول یک middleware با نام methodDescriptors تعریف کنید و توجه کنید middleware هاتون از نوع UnaryServerInterceptor تعریف کنید و پارامتر ورودی از نوع map[string]*desc.MethodDescriptor تعریف کنید و به عنوان کلید map آدرس متد RPC را بدهید و در نهایت به context خروجی append کنید.
۸. در تابع Initiate GRPC قبل از ایجاد تابع سازنده grpc.NewServer یک متغیر map[string]*desc.MethodDescriptor تعریف می کنیم سپس این متغیر را به middleware methodDescriptors می دهیم و خود middleware را به NewServer پاس می دهیم.
۹. پس ایجاد تابع سازنده grpc.NewServer متغیر srv را به تابع LoadServiceDescriptors می دهیم تا بتوانیم به آبجکت descriptor دسترسی داشته باشیم و پس از دسترسی این آبجکت را داخل یک حلقه قرار داده تا بتوانیم لیست متدها را بگیریم و پس از آن لیست متدها را داخل یک حلقه قرار داده و نام متد را به عنوان کلید map[string]*desc.MethodDescriptor می دهیم و مقدار کلید را آبجکت method descriptor را می دهیم.
۱۰. اکنون زمانیکه سرویس initiate می شود MethodDescriptor ها داخل Context های خروجی قرار میگیرد که داخل سایر Middleware ها و خود Method پیاده سازی شده از طریق context قابل دسترس است.
۱۱. حال قصد داریم به permission هایی که برای متد GetBooks تعریف کردیم دسترسی پیدا کنیم و برای اینکار کافی است داخل jwtMiddleware بیاید مقدار کلید desc را از context بگیرید و آن را به desc.MethodDescriptor* کست کنید, پس از اینکه MethodDescriptor را گرفتید تابع GetMethodOptions را به همراه Extension Fields که داخل پروتو جنریت شده هست به تابع GetExtension بدهید تا به شما یک اینترفیس بدهد و در نهایت باید شما اینترفیس را به ساختار مسیج Permission که تعریف کردید کست کنید تا بتوانید به فیلد permission_codes دسترسی پیدا کنید.
خب دوستان به پایان این آموزش رسیدیم امیدوارم تجربه جدیدی را کسب کرده باشید و همیشه در افزایش سطح دانش خود موفق باشید, اگر سوالی چیزی داشتید می توانید داخل گروه تلگرامی GolangEngineers بپرسید.
در ضمن نمونه پروژه Library داخل گیتهاب دارم توسعه می دم و سعی میکنم امکانات و سناریوهایی خوبی را در این پروژه تعریف کنم.