google cloud endpoints - javacro conference · motivation • dead simple web backends for multi-...

32
Google Cloud Endpoints Endpoints Tomislav Čoh, Calyx d.o.o.

Upload: others

Post on 20-Apr-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Google Cloud EndpointsEndpoints

Tomislav Čoh, Calyx d.o.o.

Page 2: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Summary

• Introduction

• Motivation

• Architecture• Architecture

• Demo app "Re-gifter"

• Conclusion

Page 3: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Introduction

• Experimental App Engine feature

• REST & RPC APIs for app backend

• Utilizes internal Google infrastructure• Utilizes internal Google infrastructure

• API explorer

• Client library generation:o Java / Android

o Objective C / iOS

o Javascript

Page 4: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Motivation

• Dead simple Web backends for multi-platform clients

• Utilize the power of App EngineDatastoreo Datastore

o Blobstore

o Image service

o Google OAuth2 integration

• Rich testing environment

• Enforced scalability

• Pay for what you use

Page 5: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Architecture

Page 6: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Demo appDemo appre-gifter.appspot.com

Page 7: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Development process• Project setup• Design data model• Develop business logic• Test business logic• Test business logic• Annotate endpoints• Test on local server• Deploy• Test deployed• Generate client libraries• Add authentication

Page 8: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Project setup

• Install Google Plugin for Eclipse

• Create Web Application project

• Disable DataNucleus Enhancer•o Google->App Engine->Orm

• Install Lombok

• Add Objectify to classpath

• Add Guava to classpath

• Add Lombok to classpath

• Setup Objectify

Page 9: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

web.xml:

...<filter>

<filter-name>ObjectifyFilter</filter-name><filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>

</filter><filter-mapping><filter-name>ObjectifyFilter</filter-name>

public class OfyService {

static {factory().register(Gift.class);

}

public static final Objectify ofy() {return ObjectifyService.ofy();

}

Project setup

<filter-name>ObjectifyFilter</filter-name><url-pattern>/*</url-pattern>

</filter-mapping>...

}

public static final ObjectifyFactory factory() {return ObjectifyService.factory();

}

}

Page 10: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Design data model

• Schemaless datastore• Ancestor paths and entity groups• Datastore Java API•

o Datastore low-level APIo JDO/JPAo Objectifyo Twigo Slim3

Page 11: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

@Entity@NoArgsConstructor@RequiredArgsConstructorpublic class Gift {

@Id@Getterprivate Long id;

@Parent@Setterprivate Key recipient;

Design data model

@Getter@NonNullprivate String giver;

@Getter@NonNullprivate String description;

}

Page 12: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Develop business logic

• Find gifts by recipient

• Insert a gift

Page 13: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

public class Regifter {

public List<Gift> findGiftsByRecipient(String recipientEmail) {Key recipientKey = KeyFactory.createKey("Person", recipientEmail);return ofy().load().type(Gift.class).ancestor(recipientKey).list();

}

public Gift insertGift(String recipientEmail, Gift gift) {Key recipientKey = KeyFactory.createKey("Person", recipientEmail);gift.setRecipient(recipientKey);

Develop business logic

gift.setRecipient(recipientKey);ofy().save().entity(gift).now();return gift;

}

}

Page 14: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Test

• Create test project• Add Re-gifter project to classpath• Project dependencies:o JUnit4

•o JUnit4o ${SDK_ROOT}/lib/impl/appengine-api.jaro ${SDK_ROOT}/lib/impl/appengine-api-labs.jaro ${SDK_ROOT}/lib/impl/appengine-api-stubs.jaro ${SDK_ROOT}/lib/testing/appengine-testing.jar

• Test business logic

Page 15: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

public class RegifterTest {private final LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig().setDefaultHighRepJobPolicyUnappliedJobPercentage(100));

private Regifter mRegifter;

@Beforepublic void setUp() {

helper.setUp();mRegifter = new Regifter();

}@Afterpublic void tearDown() {

helper.tearDown();}@Testpublic void allInOneTest() {

Gift gift = new Gift("[email protected]", "Cash");

Test

Gift gift = new Gift("[email protected]", "Cash");

Long giftId = mRegifter.insertGift("[email protected]", gift).getId();

List<Gift> gifts = mRegifter.findGiftsByRecipient("[email protected]");assertEquals(gifts.size(), 1);Gift loadedGift = gifts.get(0);assertEquals(gift.getDescription(), loadedGift.getDescription());assertNotNull(loadedGift.getId());assertEquals(giftId, loadedGift.getId());

}}

Page 16: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Annotate endpoints

• Expose REST & RPC API

• @Api - endpoint configuration

• @ApiMethod - method configuration• @ApiMethod - method configuration

Page 17: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

@Api(name = "regifter", version = "v1")public class Regifter {

@ApiMethod(name = "gifts.list", path = "receiver/{receiverEmail}/gift", httpMethod = HttpMethod.GET)public List<Gift> findGiftsByRecipient(@Named("receiverEmail") String recipientEmail) {

Key recipientKey = KeyFactory.createKey("Person", recipientEmail);return ofy().load().type(Gift.class).ancestor(recipientKey).list();

}

@ApiMethod(name = "gifts.insert", path = "receiver/{receiverEmail}/gift", httpMethod = HttpMethod.POST)public Gift insertGift(@Named("receiverEmail") String recipientEmail, Gift gift) {

Key recipientKey = KeyFactory.createKey("Person", recipientEmail);gift.setRecipient(recipientKey);

Annotate endpoints

gift.setRecipient(recipientKey);ofy().save().entity(gift).now();return gift;

}

}

Page 18: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Test on local server

• Run project in Eclipse

• http://localhost:8888/_ah/api/regifter/v1/

• Mocked App Engine environment• Mocked App Engine environmento jetty server instance

o in-memory datastore

o mocked app engine services

Page 19: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

$ curl --header "Content-Type: application/json" -X POST -d '{"giver": "[email protected]", "description":

"Fusilli Jerry"}' http://localhost:8888/_ah/api/regifter/v1/receiver/[email protected]/gift

{

"id" : "1",

"giver" : "[email protected]",

"description" : "Fusilli Jerry"

}

$ curl --header "Content-Type: application/json" -X POST -d '{"giver": "[email protected]", "description":

"Cash"}' http://localhost:8888/_ah/api/regifter/v1/receiver/[email protected]/gift

{

"id" : "1",

"giver" : "[email protected]",

"description" : "Cash"

}

$ curl --header "Content-Type: application/json"

http://localhost:8888/_ah/api/regifter/v1/receiver/[email protected]/gift

{

"items" : [ {

"id" : "1",

Test on local server

"id" : "1",

"giver" : "[email protected]",

"description" : "Fusilli Jerry"

} ]

}

$ curl --header "Content-Type: application/json"

http://localhost:8888/_ah/api/regifter/v1/receiver/[email protected]/gift

{

"items" : [ {

"id" : "1",

"giver" : "[email protected]",

"description" : "Cash"

} ]

}

Page 20: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Deploy

• https://appengine.google.com

• Set application id

• Authorize Google Plugin for Eclipse• Authorize Google Plugin for Eclipse

• Right Click->Google->Deploy to App Engine

• ...

• Profit

Page 21: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Test deployed

• API Explorer

• https://re-gifter.appspot.com/_ah/api/explorer

• API discovery• API discovery

• Test OAuth2 authorized APIs

Page 22: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Test deployed

Page 23: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Generate client libraries• Right Click->Google->Generate Cloud Endpoint Client Library

• App Engine Connected Android Project

o Google Cloud Endpoints

o Google Cloud Messagingo Google Cloud Messaging

Page 24: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Android:Regifter.Builder builder = new Regifter.Builder(AndroidHttp.newCompatibleTransport(), new

GsonFactory(), null);

Regifter mRegifter = builder.build();

Gift fusilliJerry = new Gift();

fusilliJerry.setGiver("[email protected]");

fusilliJerry.setDescription("Fusilli Jerry");

fusillyJerry = mRegifter.gifts().insert("[email protected]", fusilliJerry).execute();

JavaScript:<script>function onClientLoad() {

var ROOT = 'https://re-gifter.appspot.com/_ah/api';

gapi.client.load('regifter', 'v1', onLoad, ROOT);

Generate client libraries

gapi.client.load('regifter', 'v1', onLoad, ROOT);

}

function onLoad() {

gapi.client.regifter.gifts.insert('[email protected]', {giver: '[email protected]',

description: 'Fusilly Jerry'}).execute(onGiftInserted);

}

function onGiftInserted(response) {

alert('Gift given!');

}

</script>

<script src="https://apis.google.com/js/client.js?onload=onClientLoad"></script>

Page 25: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Add Authentication

• Create API Projecto https://code.google.com/apis/console

• Specify client ids• Specify client idso Browser, Server, Android, iOS

• Modify annotations

• Add User parameter to authorized methods

Page 26: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

@Api(name = "regifter", version = "v1", clientIds = Constant.API_EXPLORER_CLIENT_ID)public class Regifter {

@ApiMethod(name = "gifts.list", path = "receiver/me/gift", httpMethod = HttpMethod.GET)public List<Gift> findGiftsByRecipient(User user) {

Key recipientKey = KeyFactory.createKey("Person", user.getEmail());return ofy().load().type(Gift.class).ancestor(recipientKey).list();

}

@ApiMethod(name = "gifts.insert", path = "receiver/me/gift", httpMethod = HttpMethod.POST)public Gift insertGift(User user, Gift gift) {

Key recipientKey = KeyFactory.createKey("Person", user.getEmail());gift.setRecipient(recipientKey);

Add authentication

gift.setRecipient(recipientKey);ofy().save().entity(gift).now();return gift;

}

}

Page 27: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Add authentication

Page 28: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

ConclusionConclusionPros and Cons

Page 29: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

The good parts

• Simple

• Minimal configuration

• Lightweight• Lightweight

• Integrated services

• No server maintenance

• Deploy in seconds

• Scalability implied

Page 30: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Drawbacks and limitations

• Experimentalo Bugs

o Breaking changes

•• Unintuitive error reporting in GPE

• Cold start delay

• Framework integration discouraged

• Third party libraries

• No custom domain for endpointso CORS browser support when using REST

Page 31: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

• SQL support experimental

• JDO/JPA incompleteo no many-to-many owned relationships

o no join, aggregation, polymorphic queries

• Data migrationo Immutable keys

o New indices affect only new entities

Drawbacks and limitations

Page 32: Google Cloud Endpoints - JavaCro Conference · Motivation • Dead simple Web backends for multi- platform clients • Utilize the power of App Engine o Datastore o Blobstore o Image

Thank you!Thank you!Questions?