בדף הזה מוסבר איך להגדיר אפשרויות מתקדמות, כמו מיפוי קלט ומאפיינים וירטואליים, לספקי סוגים. סקירה כללית על סוגים מידע נוסף על ספקי סוגים זמין במדריך בן עמוד אחד לשילוב עם Deployment Manager.
אם אתם מנסים לשלב API שלא עומד בדרישות ה-API שמוגדרות על ידי Deployment Manager, אתם יכולים להשתמש במיפוי קלט ובמאפיינים וירטואליים כדי לפתור את חוסר העקביות הזה. מיפוי קלט מאפשר לספק מיפויים מפורשים של פרמטרים של API במקרים של דו-משמעות, ומאפיינים וירטואליים מאפשרים לחשוף מאפיינים שרירותיים שלא קיימים בממשקי ה-API הבסיסיים, כדי לפשט את הקלט ולהסתיר את המורכבויות של ה-API מהמשתמשים.
כדי להטמיע אפשרויות הגדרה מתקדמות, צריך להכיר היטב את ה-API שעבורו יוצרים את ספק הסוגים. מכיוון שכל API יכול להיות שונה מאוד מאחרים, בדף הזה מופיעות הנחיות כלליות ודוגמאות, אבל לא הנחיות ספציפיות ל-API.
לפני שמתחילים
- אם רוצים להשתמש בדוגמאות לשורת הפקודה במדריך הזה, צריך להתקין את כלי שורת הפקודה`gcloud`.
- כדי להשתמש בדוגמאות ל-API במדריך הזה, צריך להגדיר גישה ל-API.
- אם רוצים להשתמש בדוגמאות ל-API במדריך הזה, צריך להגדיר גישה ל-API v2beta.
- איך יוצרים הגדרה
תרחישים נפוצים שבהם נדרשות אפשרויות הגדרה מתקדמות
שם הנכס נמצא בשימוש חוזר עם ערכים שונים
בממשקי API מסוימים, יכול להיות ששם של מאפיין או פרמטר ישמש שוב בשיטות שונות, אבל עם ערכים שונים. לדוגמה, יכול להיות שב-API מסוים הפרמטר name ליצירת משאב (בקשת POST) יכול לקבל את הערך foo/bar, אבל אותו שדה name בבקשות עדכון (PATCH או PUT) יחייב את הערך foo/bar/baz.
אפשר להסיק את ערכי הנכס מתגובת ה-API
חלק מה-methods של ה-API דורשות ערך שנוצר על ידי השרת ומוחזר כששולחים בקשת GET למשאב. לדוגמה, יכול להיות ש-API ידרוש פרמטר etag כדי לבצע בקשות עדכון כשמשנים משאב. הערך של etag משתנה אחרי כל בקשת שינוי, לכן כדי לקבל את הפרמטר הנוכחי etag צריך לבצע בקשת GET למשאב לפני שמבצעים את הבקשה לעדכון המשאב.
באמצעות מיפוי קלט, אפשר להגדיר ב-Deployment Manager שאפשר לאחזר את השדה etag ממשאב ה-API. Deployment Manager מבצע באופן אוטומטי בקשה לקבלת הערך הזה כשמשתמש קורא לשיטה שציינתם במיפוי הקלט.GET
מפשטים את קלט המשתמש
Deployment Manager תומך במאפיינים וירטואליים שהם מאפיינים שרירותיים שאפשר לחשוף למשתמשים באמצעות Deployment Manager לשימושים שונים. נכסים וירטואליים הם משתנים שרירותיים שערכם לא מוגדר ב-API הבסיסי, אבל אפשר להוסיף אותם למיפוי של קלט לפי הצורך. לדוגמה, נניח שיש מאפיין API שצריך לקודד בפורמט Base64 לפני שהערך נשלח ל-API הבסיסי. במקום לבקש מהמשתמשים לספק את הערך בקידוד Base64, אפשר ליצור מאפיין וירטואלי שמבקש מהמשתמשים את הערך בטקסט רגיל, ואז לקודד את הערך ב-Base64 באמצעות מיפויי קלט, ולבסוף לספק את התוצאה ל-API הבסיסי.
ציון אפשרויות מתקדמות
כדי לציין אפשרויות מתקדמות, צריך לספק את המאפיין collectionOverrides כשיוצרים את משאב ספק הסוגים, ולהגדיר מיפויים של קלט או מאפיינים וירטואליים לכל אוסף API לפי הצורך.
לדוגמה, באמצעות ה-CLI של gcloud, אפשר לספק אפשרויות מתקדמות באמצעות קובץ YAML ולספק את קובץ ה-YAML עם הבקשה type-providers create.
קובץ YAML לדוגמה:
collectionOverrides:
- collection: /emailAddresses/v1beta/people
options:
inputMappings:
- methodMatch: ^create$
fieldName: emailAddress.displayName
value: $.resource.properties.displayName
location: BODY
- methodMatch: ^update$
fieldName: displayName
value: $.resource.properties.displayName
location: PATH
virtualProperties: |
schema: http://json-schema.org/draft-04/schema#
type: object
properties:
displayName:
type: string
credential:
basicAuth:
user: [USERNAME]
password: [PASSWORD]
ההגדרות האלה אומרות ל-Deployment Manager:
בשיטה
create, מחפשים את השדה שנקראemailAddress.displayNameבגוף המשאב ומגדירים את הערך של השדה הזה לקלט של המשתמש במאפייןdisplayNameבהגדרות של Deployment Manager. לכן, אם משתמש מגדיר את ההגדרה שלו כך:resources: - name: example type: myproject/emailAddress:/emailAddresses/v1beta/people properties: - displayName: John Doe ...Deployment Manager יגדיר את הערך של
emailAddress.displayNameל-John Doe.בשיטה
update, השדה נמצא בנתיב המשאב ולא בגוף המשאב, אבל מוחל אותו מיפוי קלט.
קביעת מיפויי קלט
מיפוי קלט מאפשר לכם למפות או להוסיף מידע לשדות מסוימים ב-API, כדי ש-Deployment Manager יוכל ליצור אינטראקציה חלקה יותר עם ה-API הבסיסי. כך המשתמשים לא צריכים להבין את ההתנהגות המורכבת של ה-API.
אפשר להשתמש במיפוי קלט כדי לפשט את האינטראקציה של המשתמשים עם ה-API. לדוגמה, אפשר להשתמש במיפוי קלט כדי לקבל באופן אוטומטי ערכים שנוצרו על ידי השרת, כמו טביעות אצבע, מזהים או תגי etag. כך המשתמשים לא צריכים לבצע בקשת get נפרדת במשאב בכל פעם שהם רוצים לבצע עדכון.
באופן דומה, אפשר גם להשתמש במיפויים של קלט כדי לטפל במצבים מעורפלים או מבלבלים שבהם לאותו שדה API יש ערכים שונים בשיטות שונות.
לדוגמה, בקשה ליצירת משאב עשויה לדרוש מאפיין name שהמשתמש יכול לציין, אבל אותו API עשוי לדרוש מאפיין name בפורמט שונה לשיטות update. אפשר להשתמש במיפוי קלט כדי לציין ל-Deployment Manager איזה ערך מתאים לכל שיטת API.
כדי לציין מיפויי קלט לספק סוגים, צריך לספק את המאפיין options.inputMappings. אפשר להגדיר מיפויי קלט שחלים על כל ה-API, או לספק במפורש מיפויי קלט לכל אוסף:
# Input mappings for the entire API
"options": {
"inputMappings": [
{
"fieldName": "[NAME]",
"location": "[PATH | BODY | QUERY | HEADER]",
"methodMatch": "[REGEX_MATCHING_CERTAIN_METHODS]",
"value": "[VALUE_TO_INJECT]"
},
{
"fieldName": "[NAME]",
"location": "[PATH | BODY | QUERY | HEADER]",
"methodMatch": "[REGEX_MATCHING_CERTAIN_METHODS]",
"value": "[VALUE_TO_INJECT]"
}
]
},
# Input mappings for specific collections
"collectionOverrides": [
{
"collection": "[SPECIFIC_COLLECTION]",
"options": {
"inputMappings": [
{
"fieldName": "[NAME]",
"location": "[PATH | BODY | QUERY | HEADER]",
"methodMatch": "[REGEX_MATCHING_CERTAIN_METHODS]",
"value": "[VALUE_TO_INJECT]"
},
{
"fieldName": "[NAME]",
"location": "[PATH | BODY]",
"methodMatch": "[REGEX_MATCHING_CERTAIN_METHODS]",
"value": "[VALUE_TO_INJECT]"
},
...[additional fields if necessary]...
]
}
}
]
בהמשך מפורט כל אחד מהחלקים החשובים בתחביר הזה.
אוסף
[SPECIFIC_COLLECTION] הוא אוסף ה-API שאליו מיפוי הקלט הזה מתייחס. לדוגמה, אם סיפקתם מיפויים של קלט למסמך Discovery של Google, כמו IAM Service Accounts API, האוספים הרלוונטיים הם projects.serviceAccounts ו-projects.serviceAccountKeys.
ב-API שמשתמש במפרט OpenAPI, נתיב האיסוף יכול להיות /example-collection/{name}. אפשר לעיין בדוגמה פונקציונלית של OpenAPI במאגר OpenAPI GitHub.
שם השדה
"fieldName" הוא מאפיין או נכס של API שרוצים לציין עבורו את מיפוי הקלט. לדוגמה, "fieldName": "fingerprint", "fieldName": "etag" וכן הלאה.
Location
מאפייני API יכולים להופיע כפרמטרים בנתיב כתובת ה-URL, או כחלק מגוף הבקשה או התגובה. מציינים איפה מיפוי הקלט הזה חל, למשל כתובת ה-URL PATH או הבקשה BODY כמיקום. הערכים הנתמכים כוללים:
PATHBODYQUERYHEADER
Method match
מציינים לאילו שיטות מיפוי הקלט הזה חל. משתמשים בביטוי רגולרי כדי לציין כמה שיטות. לדוגמה:
"methodMatch":"^create$"
במפרטים של OpenAPI, אפשר:
"methodMatch: ^(put|get|delete|post)$"
ערך
מציינים את הערך ש-Deployment Manager צריך להוסיף לשדה הזה.
השדה הזה משתמש בסימון JSONPath.
לדוגמה, מיפוי הקלט הזה אומר שעבור השדה name, Deployment
Manager צריך לקחת את הערך שהמשתמש סיפק ולהוסיף אותו לפורמט
projects/$.project/topics/$resource.properties.topic:
"inputMappings":[
{
"fieldName":"name",
"location":"PATH",
"methodMatch":"^post$",
"value":"concat(\"projects/\", $.project, \"/topics/\", $.resource.properties.topic)"
}...
כשמשתמשים ב-
$.resource.properties.[VARIABLE], מגדירים ערך למאפיין שהמשתמש יגדיר בהגדרות שלו. לדוגמה, עבור$.resource.properties.topic, הערך יהיה הערך שהמשתמש סיפק למאפייןtopicבהגדרה שלו:resources: - name: example type: example-type-provider:collectionA properties: topic: history # The value of "history" would be used for the `name` parameter because of the input mapping aboveכדי להפנות למשאב עצמו אחרי בקשת
get, משתמשים ב-$.resource.self.[VARIABLE]. לדוגמה, אם רוצים לקבל את טביעת האצבע העדכנית בבקשות עדכון, אפשר להשתמש בתחביר הזה כדי להנחות את Deployment Manager לבצעgetולשלוף את הערך:{ 'fieldName': 'fingerprint', 'location': 'BODY', 'methodMatch': '^(put)$', # self represents the resource by doing a GET on it. # This mappings gets latest fingerprint on the request. # Final PUT Body will be # { # "name": "my-resource-name", # "fingerprint": "<server generated fingerprint>" # } 'value': '$.resource.self.fingerprint' }
שימוש במאפיינים וירטואליים
מאפיינים וירטואליים הם מאפיינים שרירותיים שאפשר לחשוף למשתמשים באמצעות Deployment Manager. המאפיינים האלה לא מהווים חלק מה-API הבסיסי, אלא הם משתנים שרירותיים שאפשר להשתמש בהם כדי להעביר מידע או להסתיר אי-התאמות ב-API מהמשתמשים. אפשר גם להפנות למאפיינים וירטואליים במיפויי הקלט.
מאפיינים וירטואליים פועלים לפי סכימת JSON 4. צריך לספק נכסים וירטואליים כחלק מהמאפיין options לאוסף ספציפי:
"collection": "[SPECIFIC_COLLECTION]",
"options": {
"virtualProperties": "schema: http://json-schema.org/draft-04/schema#\ntype: object\nproperties:\n [PROPERTY]:\n type: [DATA_TYPE]\n [ANOTHER_PROPERTY]:\n type: [ANOTHER_DATA_TYPE]n"
"inputMappings": [
...
]
}
בקובץ הגדרה ב-YAML, זה ייראה כך:
- collection: projects.serviceAccounts
options:
virtualProperties: |
schema: http://json-schema.org/draft-04/schema#
type: object
properties:
a-property:
type : string
b-property:
type : string
required:
- a-property
- b-property
inputMappings:
...
לדוגמה, נניח שיש API מזויף שיוצר כתובות אימייל. נניח של-API יש שיטה ליצירת אימייל שמקבלת מאפיין emailAddress.displayName. כשמשתמש שולח בקשה ליצירת כתובת אימייל, הוא מציין בקשה כזו:
POST https://example.com/emailAddresses/v1beta/people/
{
"emailAddress": {
"displayName": "john"
}
}
נניח ש-API מסוים מאפשר לעדכן את כתובת האימייל, אבל ה-method לעדכון כתובת האימייל דורש רק את המאפיין displayName ולא את המאפיין email.displayName:
POST https://example.com/emailAddresses/v1beta/people/john
{
"displayName": "josh"
}
איך אתם מצפים שהמשתמשים יספקו את הערך הזה כשהם משתמשים בסוג הזה של ספק? אפשר לבקש מהם לציין את הנכס בצורה אחרת בהתאם לפעולה:
# Creating an email
resources:
- name: example-config
type: projects/test-project:emailAddresses
properties:
emailAddress:
displayName: john
# Updating an email
resources:
- name: example-config
type: projects/test-project:emailAddresses
properties:
displayName: john
לחלופין, אפשר ליצור מאפיין וירטואלי שמקבל את אותו ערך, ללא קשר לפעולה, ואז להשתמש במיפויי קלט כדי למפות את המאפיין הווירטואלי לפרמטר המתאים ב-API. בדוגמה הזו, נניח שהגדרתם נכס וירטואלי בשם displayName. מיפוי הקלט יכול להיראות כך:
{
"collectionOverrides":[
{
"collection":"emailAddresses",
"options":{
"inputMappings":[
{
"fieldName":"emailAddress.displayName",
"location":"BODY",
"methodMatch":"^create$",
"value":"$.resource.properties.displayName"
},
{
"fieldName":"displayName",
"location":"BODY",
"methodMatch":"^update$",
"value":"$.resource.properties.displayName"
}
],
"virtualProperties":"schema: http://json-schema.org/draft-04/schema#\ntype: object\nproperties:\n displayName:\n type: string\nrequired:\n- displayName\n"
}
}
],
"descriptorUrl":"https://example.com/emailAddresses/v1beta/",
"options":{
"nameProperty":""
}
}
באופן ספציפי, המאפיין הווירטואלי מוגדר כאן:
"virtualProperties":"schema: http://json-schema.org/draft-04/schema#\ntype: object\nproperties:\n displayName:\n type: string\nrequired:\n- displayName\n"
בפורמט קריא לאנשים:
"virtualProperties":
"schema: http://json-schema.org/draft-04/schema#\n
type: object\n
properties:\n
displayName:\n
- type: string\n
required:\n
- displayName\n"
מעכשיו, המשתמשים יכולים לציין את displayName כנכס ברמה העליונה גם בבקשות לעדכון וגם בבקשות ליצירה, ומערכת Deployment Manager תדע איך למפות את הערך בצורה נכונה.
# Creating an email
resources:
- name: example-config
type: projects/test-project:emailAddresses
properties:
displayName: john
# Updating an email
resources:
- name: example-config
type: projects/test-project:emailAddresses
properties:
displayName: john
המאמרים הבאים
- איך משתמשים בספק סוגים
- מידע נוסף על סוגים
- מידע נוסף על יצירת הגדרה
- יצירת פריסה.
- איך יוצרים סוג מורכב