הערות ותחביר של Cloud Endpoints Frameworks

ההערות של Endpoints Frameworks מתארות את ההגדרות, השיטות, הפרמטרים ופרטים חיוניים אחרים של ה-API שמגדירים את המאפיינים וההתנהגות של נקודת הקצה.

במאמר כתיבה והוספת הערות לקוד מוסבר איך להוסיף הערות באמצעות פרויקט Maven. ‫Maven App Engine Cloud Endpoints artifacts מסופקים כדי ליצור ולבנות API של קצה עורפי, וליצור ממנו ספריית לקוח.

ההערה שמציינת את ההגדרה וההתנהגות של ה-API כולו (משפיעה על כל המחלקות שנחשפות ב-API ועל כל השיטות שנחשפות שלהן) היא @Api. כל ה-methods הציבוריים, הלא סטטיים והלא מגשרים של מחלקה עם אנוטציה @Api נחשפים ב-API הציבורי.

אם אתם צריכים הגדרת API מיוחדת לשיטה מסוימת, אתם יכולים להשתמש ב-@ApiMethod כדי להגדיר את ההגדרות לכל שיטה בנפרד. כדי להגדיר את האנוטציות האלה, צריך להגדיר מאפיינים שונים, כמו שמוצג בטבלאות הבאות.

@Api: הערות בהיקף API

ההערה @Api מגדירה את כל ה-API, והיא חלה על כל השיטות הציבוריות של מחלקה אלא אם היא מוחלפת על ידי @ApiMethod.

כדי לשנות הערה מסוימת @Api עבור מחלקה ספציפית ב-API, אפשר לעיין במאמרים @ApiClass ו@ApiReference.

ייבוא חובה

כדי להשתמש בתכונה הזו, צריך לייבא את הפונקציה הבאה:

import com.google.api.server.spi.config.Api;

מאפיינים

@Api Attributes תיאור דוגמה
audiences חובה אם ה-API דורש אימות ואם אתם תומכים בלקוחות Android. מידע נוסף זמין במאמר בנושא מזהי לקוח וקהלים. audiences = {"1-web-apps.apps.googleusercontent.com", "2-web-apps.apps.googleusercontent.com"}
apiKeyRequired זה שינוי אופציונלי. ההגבלה הזו משמשת להגבלת הגישה לבקשות שכוללות מפתח API. apiKeyRequired = AnnotationBoolean.TRUE
authenticators חובה אם ה-API מאומת באמצעות Firebase,‏ Auth0 או חשבונות שירות. המאפיין הזה לא נדרש אם האימות של ה-API מתבצע באמצעות אסימונים מזהים של Google. אפשר להגדיר את זה ברמת ה-API או ברמה של שיטה ספציפית. אפשר להגדיר אותו ל-{EspAuthenticator.class}, או לכתוב מאמת חשבונות מותאם אישית משלכם, כמו שמתואר במאמר Interface Authenticator. authenticators = {EspAuthenticator.class}
backendRoot הוצאה משימוש, כדי להציג את ה-API מנתיב אחר, משנים את url-pattern בקטע EndpointsServlet בקובץ web.xml. <url-pattern>/example-api/*</url-pattern>
canonicalName המאפיין הזה משמש לציון שם אחר או קריא יותר ל-API בספריית הלקוח. השם הזה משמש ליצירת השמות בספריית הלקוח. ה-API של ה-Backend ממשיך להשתמש בערך שצוין במאפיין name.

לדוגמה, אם במאפיין name של ה-API מוגדר הערך dfaanalytics, אפשר להשתמש במאפיין הזה כדי לציין שם קנוני של DFA Group Analytics. לאחר מכן, המחלקות של הלקוח שנוצרו יכללו את השם DfaGroupAnalytics.

צריך לכלול את הרווחים הרלוונטיים בין השמות. הרווחים האלה מוחלפים בסימון camel case או בקו תחתון.
canonicalName = "DFA Analytics:"n
clientIds חובה אם ה-API שלכם משתמש באימות. רשימה של מזהי לקוחות שמורשים לבקש טוקנים. מידע נוסף זמין במאמר בנושא מזהי לקוח וקהלים. clientIds = {"1-web-apps.apps.googleusercontent.com", "2-android-apps.apps.googleusercontent.com"}
defaultVersion המדיניות הזו קובעת אם נעשה שימוש בגרסת ברירת מחדל אם לא צוינה גרסה במאפיין version. defaultVersion = AnnotationBoolean.TRUE
description תיאור קצר של ה-API. הוא נחשף בשירות הגילוי כדי לתאר את ה-API, ואפשר גם להשתמש בו כדי ליצור תיעוד. description = "Sample API for a simple game"
documentationLink כתובת ה-URL שבה המשתמשים יכולים למצוא תיעוד לגבי הגרסה הזו של ה-API. המידע הזה מוצג ב-API Explorer בקטע 'מידע נוסף' בחלק העליון של הדף, כדי שהמשתמשים יוכלו לקבל מידע על השירות שלכם. documentationLink = "http://link_to/docs"
issuers הגדרות מותאמות אישית של מנפיק JWT. issuers = { @ApiIssuer(name = "auth0", issuer = "https://test.auth0.com/authorize", jwksUri = "https://test.auth0.com/.well-known/jwks.json") }
issuerAudiences קהלים למנפיקים ספציפיים. issuerAudiences = { @ApiIssuerAudience(name = "auth0", audiences = {"aud-1.auth0.com", "aud-2.auth0.com"}) }
limitDefinitions זה שינוי אופציונלי. משמש להגדרת מכסות ל-API. מידע נוסף מפורט ב@ApiLimitMetric. limitDefinitions = { @ApiLimitMetric(name = "read-requests", displayName = "Read requests", limit = 1000)}
name שם ה-API, שמשמש כקידומת לכל ה-methods והנתיבים של ה-API. הערך של name:
  • חייב להתחיל באות קטנה
  • חייב להתאים לביטוי הרגולרי [a-z]+[A-Za-z0-9]*
אם לא מציינים את name, המערכת משתמשת בברירת המחדל myapi.
name = "foosBall"
namespace הגדרת מרחב שמות ללקוחות שנוצרו. מידע נוסף מפורט ב@ApiNamespace. namespace=@ApiNamespace(ownerDomain="your-company.com", ownerName="YourCo", packagePath="cloud/platform")
root הוצאה משימוש, כדי להציג את ה-API מנתיב אחר, בקובץ web.xml, משנים את url-pattern בקטע EndpointsServlet. <url-pattern>/example-api/*</url-pattern>
scopes אם לא מספקים את הפרמטר הזה, ברירת המחדל היא היקף האימייל (https://www.googleapis.com/auth/userinfo.email), שנדרש ל-OAuth. אם רוצים, אפשר לעקוף את ההגדרה הזו כדי לציין עוד היקפי הרשאות OAuth 2.0. עם זאת, אם מגדירים יותר מהיקף אחד, חשוב לדעת שבדיקת ההיקף עוברת אם האסימון נוצר עבור אחד מההיקפים שצוינו. כדי לדרוש כמה היקפים, צריך לציין String אחד עם רווח בין כל היקף. כדי לבטל את ההיקפים שצוינו כאן עבור שיטת API מסוימת, מציינים היקפים שונים בהערת @ApiMethod. scopes = {"ss0", "ss1 and_ss2"}
title הטקסט שמוצג ב-API Explorer ככותרת של ה-API, ומוצג בשירותי הגילוי והספרייה. title = "My Backend API"
transformers מציינת רשימה של טרנספורמרים מותאמים אישית. שימו לב שיש הערה חלופית (@ApiTransformer) שעדיפה. המאפיין הזה מוחלף על ידי @ApiTransformer. transformers = {BazTransformer.class}
version מציינים את הגרסה של נקודת הקצה. אם לא מציינים את הערך הזה, המערכת משתמשת בערך ברירת המחדל v1. version = "v2"

הערה לדוגמה@Api

האנוטציה הזו ממוקמת לפני הגדרת המחלקה:

/** An endpoint class we are exposing. */
@Api(name = "myApi",
    version = "v1",
    namespace = @ApiNamespace(ownerDomain = "helloworld.example.com",
        ownerName = "helloworld.example.com",
        packagePath = ""))

מזהי לקוחות וקהלים

באימות OAuth2, טוקן OAuth2 מונפק למזהה לקוח ספציפי, מה שאומר שאפשר להשתמש במזהה הלקוח כדי להגביל את הגישה לממשקי ה-API. כשרושמים אפליקציה ל-Android ב Google Cloud מסוף, נוצר עבורה מזהה לקוח. מזהה הלקוח הזה הוא זה שמבקש טוקן OAuth2 מ-Google למטרות אימות. כשממשק ה-API של ה-Backend מוגן על ידי אימות, נשלח אסימון גישה של OAuth2 והוא נפתח על ידי Endpoints. מזהה הלקוח מחולץ מהאסימון ואז המזהה מושווה לרשימת מזהי הלקוחות המקובלים שהוגדרו ב-Backend (רשימת clientIds).

אם רוצים שממשק ה-API של Endpoints יאמת את המתקשרים, צריך לספק רשימה של clientIds שמורשים לבקש טוקנים. הרשימה הזו צריכה לכלול את כל מזהי הלקוחות שהשגתם באמצעותGoogle Cloud console עבור לקוחות האינטרנט או Android שלכם. כלומר, הלקוחות צריכים להיות ידועים בזמן בניית ה-API. אם מציינים רשימה ריקה, {}, אף לקוח לא יכול לגשת לשיטות שמוגנות על ידי Auth.

אם אתם משתמשים במאפיין clientIds ורוצים לבדוק קריאות מאומתות ל-API באמצעות Google API Explorer, אתם צריכים לספק את מזהה הלקוח שלו ברשימה של clientIds. הערך שצריך להשתמש בו הוא com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID.

מידע על קהלים

הרשימה clientIds מגנה על ה-API של הקצה העורפי מפני לקוחות לא מורשים. אבל נדרשת הגנה נוספת כדי להגן על הלקוחות, כך שרק ה-API המיועד בקצה העורפי יוכל להשתמש באסימון האימות שלהם. בממשקי API של בק-אנד, המנגנון הזה הוא מאפיין audiences, שבו מציינים את מזהה הלקוח של ה-API.

שימו לב: כשיוצרים פרויקט במסוף Google Cloud , נוצר באופן אוטומטי מזהה לקוח שמוגדר כברירת מחדל, והוא נקרא על שם הפרויקט. כשמעלים את ה-API של ה-Backend אל App Engine, המערכת משתמשת במזהה הלקוח הזה. זהו מזהה לקוח האינטרנט שמוזכר במאמר בנושא אימות API.

@ApiMethod: הערות בהיקף של שיטה

ההערה @ApiMethod משמשת כדי לספק הגדרת API שונה מהגדרות ברירת המחדל שסופקו על ידי ההערות @Api או @ApiClass. שימו לב: זהו שלב אופציונלי. כל המתודות הציבוריות, הלא סטטיות והלא מגשרות במחלקה עם אנוטציית @Api נחשפות ב-API, בין אם יש להן אנוטציית @ApiMethod ובין אם לא.

המאפיינים בתוך ההערה הזו מאפשרים להגדיר פרטים של רכיב method יחיד של API. אם אותו מאפיין מצוין ב-@Api וב-@ApiMethod, המאפיין @ApiMethod מבטל את המאפיין @Api.

ייבוא חובה

כדי להשתמש בתכונה הזו, צריך לייבא את הפונקציות הבאות:

import com.google.api.server.spi.config.AnnotationBoolean;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiMethod.HttpMethod;

מאפיינים

מאפיינים של ‎@ApiMethod תיאור דוגמה
apiKeyRequired זה שינוי אופציונלי. ההגבלה הזו משמשת להגבלת הגישה לבקשות שכוללות מפתח API. apiKeyRequired = AnnotationBoolean.TRUE
audiences צריך לספק את הערך הזה אם רוצים לבטל את ההגדרה ב-@API. מידע נוסף זמין במאמר בנושא מזהי לקוח וקהלים. audiences = {"1-web-apps.apps.googleusercontent.com", "2-web-apps.apps.googleusercontent.com"}
authenticators חובה אם ה-API מאומת באמצעות Firebase,‏ Auth0 או חשבונות שירות, ולא הגדרתם את המאפיין הזה ברמת ה-API. המאפיין הזה לא נדרש אם האימות של ה-API מתבצע באמצעות אסימונים מזהים של Google. מגדירים אותו ל-{EspAuthenticator.class}, או שכותבים מאמת חשבונות מותאם אישית משלכם, כמו שמתואר במאמר Interface Authenticator. authenticators = {EspAuthenticator.class}
clientIds רשימה של מזהי לקוחות שמורשים לבקש טוקנים. חובה אם ה-API שלכם משתמש באימות. clientIds = {"1-web-apps.apps.googleusercontent.com", "2-android-apps.apps.googleusercontent.com"}
httpMethod שיטת ה-HTTP שבה רוצים להשתמש. אם לא מגדירים את זה, המערכת בוחרת ברירת מחדל על סמך שם השיטה. httpMethod = HttpMethod.GET
issuerAudiences צריך לספק את הערך הזה אם רוצים לבטל את ההגדרה ב-@Api. issuerAudiences = { @ApiIssuerAudience(name = "auth0", audiences = {"aud-1.auth0.com", "aud-2.auth0.com"}) }
metricCosts זה שינוי אופציונלי. השדה מציין שלשיטה יש הגבלת מכסה. אתם מקצים את ההערה @ApiMetricCost ל-metricCosts. צריך לציין גם את המאפיין limitDefinitions כדי להגדיר את המכסה בהערה @Api. @ApiMetricCostההערה כוללת את המאפיינים הבאים:
  • name: שם שציינתם בהערה ApiLimitMetric.
  • cost: מספר שלם שמציין את העלות של כל בקשה. העלות מאפשרת לשיטות לצרוך בשיעורים שונים מאותה מכסה. לדוגמה, אם למכסה יש מגבלה של 1,000 ועלות של 1, האפליקציה שקוראת ל-API יכולה לשלוח 1,000 בקשות בדקה לפני שהיא חורגת מהמגבלה. אם העלות היא 2 לאותה מכסת שימוש, אפליקציית שיחות יכולה לשלוח רק 500 בקשות בדקה לפני שהיא חורגת מהמגבלה.
metricCosts = { @ApiMetricCost(name = read-requests", cost = 1) }
name השם של השיטה הזו בספריית הלקוח שנוצרה. השם הזה מקבל באופן אוטומטי קידומת של שם ה-API כדי ליצור שם ייחודי ל-method. הערך של name:
  • חייב להתחיל באות קטנה
  • חייב להתאים לביטוי הרגולרי [a-z]+[A-Za-z0-9]*
אם לא מציינים את name, המערכת משתמשת בברירת המחדל myapi.
name = "foosBall.list"
path נתיב ה-URI שמשמש לגישה לשיטה הזו. אם לא מגדירים את הנתיב, המערכת משתמשת בנתיב ברירת המחדל על סמך שם שיטת Java. אם אתם מתכננים להוסיף ניהול API, אל תכללו לוכסן בסוף הנתיב. path = "foos"
scopes צריך לציין היקף הרשאות אחד או יותר של OAuth 2.0, שאחד מהם נדרש כדי לקרוא לשיטה הזו. אם מגדירים את scopes לשיטה, ההגדרה הזו מבטלת את ההגדרה בהערה @Api. אם מגדירים יותר מהיקף אחד, חשוב לדעת שבדיקת ההיקף עוברת אם האסימון נוצר עבור אחד מההיקפים שצוינו. כדי לדרוש כמה היקפי הרשאה, מציינים String אחד עם רווח בין כל היקף הרשאה. scopes = {"ss0", "ss1 and_ss2"}

הערה לדוגמה בנושא @ApiMethod

האנוטציה הזו ממוקמת לפני הגדרת ה-method בתוך המחלקה:

/** A simple endpoint method that takes a name and says Hi back. */
@ApiMethod(
    name = "sayHiUser",
    httpMethod = ApiMethod.HttpMethod.GET)
public MyBean sayHiUser(@Named("name") String name, User user)
    throws OAuthRequestException, IOException {
  MyBean response = new MyBean();
  response.setData("Hi, " + name + "(" + user.getEmail() + ")");

  return response;
}

ב-methods שבהן יש פרמטר של ישות צריך להשתמש ב-HttpMethod.POST (לפעולות הוספה) או ב-HttpMethod.PUT (לפעולות עדכון):

@ApiMethod(
    name = "mybean.insert",
    path = "mybean",
    httpMethod = ApiMethod.HttpMethod.POST
)
public void insertFoo(MyBean foo) {
}

@Named

חובה להשתמש בהערה @Named לכל הפרמטרים שאינם מסוג ישות שמועברים לשיטות בצד השרת. ההערה הזו מציינת את שם הפרמטר בבקשה שמוזרקת לכאן. פרמטר שלא מופיעה לפניו ההערה @Named מקבל את אובייקט הבקשה כולו.

ייבוא חובה

כדי להשתמש בתכונה הזו, צריך לייבא את הפונקציות הבאות:

import javax.inject.Named;

בדוגמה הזו אפשר לראות איך משתמשים ב-@Named:

/** A simple endpoint method that takes a name and says Hi back. */
@ApiMethod(name = "sayHi")
public MyBean sayHi(@Named("name") String name) {
  MyBean response = new MyBean();
  response.setData("Hi, " + name);

  return response;
}

כאשר @Named מציין שרק הפרמטר id מוזרק לבקשה.

@ApiLimitMetric

בקטע הזה מתוארות ההערות הנדרשות להגדרת מכסות ל-API. במאמר הגדרת מכסות מפורטים כל השלבים שנדרשים להגדרת מכסה.

מקצים את ההערה @ApiLimitMetric למאפיין limitDefinitions של הערות בהיקף API. צריך גם להוסיף את @ApiMetricCost להערות @ApiMethod של כל שיטה שרוצים להחיל עליה מכסה.

ייבוא חובה

כדי להשתמש בתכונה הזו, צריך לייבא את הפונקציה הבאה:

import com.google.api.server.spi.config.ApiLimitMetric;

מאפיינים

מאפיינים של @ApiLimitMetric

תיאור
name השם של המכסה. בדרך כלל, זהו סוג הבקשה (לדוגמה, read-requests או write-requests) שמזהה באופן ייחודי את המכסה
displayName הטקסט שמוצג לזיהוי המכסה בכרטיסייה Quotas בדף Endpoints > Services במסוף Google Cloud . הטקסט הזה מוצג גם לצרכני ה-API שלכם בדף Quotas בקטע IAM & admin ובקטע API & services. השם המוצג יכול לכלול עד 40 תווים.
כדי שהשם יהיה קריא, הטקסט 'per minute per project' מצורף אוטומטית לשם התצוגה בדפים Quotas.
כדי לשמור על עקביות עם השמות המוצגים של שירותי Google שמופיעים בדפי Quotas שצרכני ה-API רואים, מומלץ להשתמש בשם המוצג הבא:
  • משתמשים באפשרות 'בקשות' כשיש רק מדד אחד.
  • אם יש לכם כמה מדדים, כל אחד מהם צריך לתאר את סוג הבקשה ולכלול את המילה requests (בקשות) (לדוגמה, Read requests (בקשות קריאה) או Write requests (בקשות כתיבה)).
  • אם אחד מהעלויות של המכסה הזה גדול מ-1, צריך להשתמש ב'יחידות מכסה' במקום ב'בקשות'.
הגבלה ערך מספרי של מספר הבקשות המקסימלי לדקה לכל פרויקט צרכן במכסה.

דוגמה

limitDefinitions = {
      @ApiLimitMetric(
        name = "read-requests",
        displayName = "Read requests",
        limit = 1000),
      @ApiLimitMetric(
        name = "write-requests",
        displayName = "Write requests",
        limit = 50),
    }

@ApiNamespace

ההערה @ApiNamespace גורמת לכך שבספריות הלקוח שנוצרות יהיה מרחב שמות שאתם מציינים, ולא מרחב שמות שנוצר כברירת מחדל במהלך יצירת ספריית הלקוח.

כברירת מחדל, אם לא משתמשים בהערה הזו, מרחב השמות שבו נעשה שימוש הוא ההיפוך של your-project-id.appspot.com. כלומר, נתיב החבילה הוא com.appspot.your-project-id.yourApi.

אפשר לשנות את מרחב השמות שמוגדר כברירת מחדל באמצעות האנוטציה @ApiNamespace בתוך האנוטציה @Api:

/** An endpoint class we are exposing. */
@Api(name = "myApi",
    version = "v1",
    namespace = @ApiNamespace(ownerDomain = "helloworld.example.com",
        ownerName = "helloworld.example.com",
        packagePath = ""))

מגדירים את מאפיין ownerDomain לדומיין של החברה ואת מאפיין ownerName לשם החברה, לדוגמה, your-company.com. ההיפוך של ownerDomain משמש לנתיב החבילה: com.your-company.yourApi.

אפשר גם להשתמש במאפיין packagePath כדי להגדיר היקף נוסף. לדוגמה, אם מגדירים את packagePath ל-cloud, נתיב החבילה שמשמש בספריית הלקוח הוא com.your-company.cloud.yourApi. אפשר להוסיף עוד ערכים לנתיב החבילה על ידי ציון התו המפריד /: packagePath="cloud/platform".

@Nullable

ההערה הזו מציינת שפרמטר של שיטה הוא אופציונלי (ולכן הוא פרמטר של שאילתה). אפשר להשתמש בסוג @Nullable רק עם @Namedפרמטרים.

@ApiClass

ב-multiclass API, אפשר להשתמש ב-@ApiClass כדי לציין מאפיינים שונים למחלקה מסוימת, ולבטל מאפיינים מקבילים בהגדרת @Api. תיאור מלא של ההערה הזו מופיע במאמר שימוש ב-@ApiClass לנכסים שיכולים להיות שונים בין סוגים.

@ApiReference

ב-multiclass API, אפשר להשתמש ב-@ApiReference כדי לספק שיטה חלופית להורשת הערות. תיאור מלא של ההערה הזו מופיע במאמר בנושא שימוש ב@ApiReferenceהורשה.

@ApiResourceProperty

@ApiResourceProperty מאפשרת לשלוט באופן החשיפה של מאפייני המשאבים ב-API. אפשר להשתמש בו בפונקציית getter או setter של נכס כדי להשמיט את הנכס ממשאב API. אפשר גם להשתמש בו בשדה עצמו, אם השדה פרטי, כדי לחשוף אותו ב-API. אפשר להשתמש בהערה הזו גם כדי לשנות את השם של מאפיין במשאב API.

ייבוא חובה

כדי להשתמש בתכונה הזו, צריך לייבא את הפונקציות הבאות:

import com.google.api.server.spi.config.ApiResourceProperty;
import com.google.api.server.spi.config.AnnotationBoolean;

מאפיינים

מאפיינים של @ApiResourceProperty תיאור דוגמה
ignored אם הערך הוא AnnotationBoolean.TRUE, המאפיין מושמט. אם לא מציינים ערך או מגדירים את הערך AnnotationBoolean.FALSE, המאפיין לא מושמט. @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
name אם מציינים את שם הנכס, הוא ייחשף ב-API. @ApiResourceProperty(name = "baz")

כיתה לדוגמה עם @ApiResourceProperty

קטע הקוד הבא מציג מחלקה עם מאפייני getter שמוגדרות להם אנוטציות באמצעות @ApiResourceProperty:


class Resp {
  private String foobar = "foobar";
  private String bin = "bin";

  @ApiResourceProperty
  private String visible = "nothidden";

  @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
  public String getBin() {
    return bin;
  }

  public void setBin(String bin) {
    this.bin = bin;
  }

  @ApiResourceProperty(name = "baz")
  public String getFoobar() {
    return foobar;
  }

  public void setFoobar(String foobar) {
    this.foobar = foobar;
  }
}

public Resp getResp() {
  return new Resp();
}

בקטע הקוד הקודם, ההגדרה @ApiResourceProperty חלה על הפונקציה getBin getter של המאפיין bin, וההגדרה של המאפיין ignored אומרת ל-Endpoints Frameworks להשמיט את המאפיין הזה במשאב של ה-API.

ההערה @ApiResourceProperty חלה גם על השדה הפרטי visible, שאין לו getter או setter. השימוש בהערה הזו חושף את השדה הזה כמאפיין במשאב ה-API.

באותו קטע, הפונקציה @ApiResourceProperty מוחלת גם על פונקציית getter אחרת, getFoobar, שמחזירה ערך מאפיין עבור המאפיין foobar. המאפיין name בהערה הזו מציין ל-Endpoints Frameworks לשנות את שם המאפיין במשאב ה-API. ערך המאפיין עצמו לא משתנה.

בדוגמה שלמעלה, ייצוג ה-JSON של אובייקט Resp נראה כך:

{"baz": "foobar", "visible": "nothidden"}

@ApiTransformer

ההערה @ApiTransformer קובעת איך סוג נתונים נחשף ב-Endpoints באמצעות טרנספורמציה מסוג נתונים אחד לסוג נתונים אחר. (הטרנספורמציה שצוינה צריכה להיות הטמעה של com.google.api.server.spi.config.Transformer.)

הדרך המומלצת לציין טרנספורמר היא באמצעות האנוטציה @ApiTransformer במחלקה. אבל אפשר גם לציין את הטרנספורמציה המותאמת אישית בtransformer מאפיין של הערת @Api.

ייבוא חובה

כדי להשתמש בתכונה הזו, צריך לייבא את הפונקציה הבאה:

import com.google.api.server.spi.config.ApiTransformer;

כיתה לדוגמה עם @ApiTransformer

בקטע הקוד הבא אפשר לראות מחלקה שמוגדרת לה אנוטציה באמצעות @ApiTransformer:


@ApiTransformer(BarTransformer.class)
public class Bar {
  private final int x;
  private final int y;

  public Bar(int x, int y) {
    this.x = x;
    this.y = y;
  }

  public int getX() {
    return x;
  }

  public int getY() {
    return y;
  }
}

הכיתה הזו עוברת טרנספורמציה על ידי הכיתה BarTransformer.

דוגמה למחלקה של טרנספורמציה של נקודות קצה

בקטע הקוד הבא מוצגת דוגמה למחלקת טרנספורמציה בשם BarTransformer. זהו הטרנספורמטור שאליו מתייחס @ApiTransformer בקטע הקוד הקודם:

public class BarTransformer implements Transformer<Bar, String> {
  public String transformTo(Bar in) {
    return in.getX() + "," + in.getY();
  }

  public Bar transformFrom(String in) {
    String[] xy = in.split(",");
    return new Bar(Integer.parseInt(xy[0]), Integer.parseInt(xy[1]));
  }
}

בהנחה שיש אובייקט עם מאפיין bar מסוג Bar, ללא הטרנספורמציה הקודמת, האובייקט מיוצג כך:

{"bar": {"x": 1, "y": 2}}

אחרי השינוי, האובייקט ייוצג כך:

{"bar": "1,2"}