SlideShare a Scribd company logo
Restaurant Server
I skipped the server creation tutorial before as I felt it left the domain of Codename One too much and ventured into server programming. In this level we don’t skip such
things so I’m going to review the server code related to the restaurant app and why it was built like that.
Restaurant Server
✦ I will not go into all of the details because many
pieces are mundane and boring
✦ The server portion is relatively easier when we have a
client ready but there is a lot of hidden complexity
✦ This is especially true when it comes to security
which is often unintuitive
© Codename One 2017 all rights reserved
I find server programming to be boring. That’s not a bad thing, boring can be great when you need something you can rely on which is exactly what a good server should
be. I’ll try to focus on the interesting pieces only and I won’t even mention some of the entities or their relations as they are just “more of the same”. There are some great
Java EE and Spring Boot courses out there and I don’t think it’s our place to displace them.

Because we did the client first the server portion is mostly filling in the blanks, there are still some hidden complex nuggets but it’s mostly simple.

Security is one of the more challenging things about server programming, I’ll try to explain as much as I can but once you go into security there is always more to know…
It’s a specialty in its own right.
Standard Spring Boot project
✦We’ll create pretty much the same spring boot project
we created in the spring boot tutorial
✦I’ll go with a new Database URL to start fresh and
new project name “AppBackendServer”. The generic
name makes sense for the app maker…
✦My goal isn’t to win an “architecture award” but to
create the bare minimum server within reason
© Codename One 2017 all rights reserved
Our starting point will be the same spring boot project I did in the base course. 

I’ll use mysql again and create a blank database. We’ll use app backend server as the project name. The same database & project will be used for the app maker as well
as the app itself.

There are some nuances in Spring such as service components which are similar to sessions beans in Java EE. I’m not using any of those things which would make
sense in an architectural standpoint but aren’t really useful for our narrow use case.
<dependency>
<groupId>com.braintreepayments.gateway</groupId>
<artifactId>braintree-java</artifactId>
<version>2.71.0</version>
</dependency>
BrainTree Support - pom.xml
Lets start right away, assuming the project was created adding braintree support to the server side starts with editing the pom file with the right dependency. This will
allow us to compile the code that supports braintree
@Controller
@RequestMapping("/braintree")
public class BraintreePaymentService {
@Autowired
private RestaurantRepository restaurantRepository;
@Autowired
private OrderRepository orderRepository;
private WeakHashMap<String, BraintreeGateway> gatewayCache = new WeakHashMap<>();
private BraintreeGateway getGateway(String auth) {
BraintreeGateway bg = gatewayCache.get(auth);
if(bg != null) {
return bg;
}
RestaurantEntity r = restaurantRepository.findOne(auth);
if(r != null) {
bg = new BraintreeGateway(
Environment.SANDBOX,
r.getMerchantId(),
r.getPublicKey(),
r.getPrivateKey()
);
gatewayCache.put(auth, bg);
return bg;
}
return null;
}
BraintreePaymentService
The braintree service is pretty simple, it maps to the braintree URL. The first thing we do is provide access to the braintree gateway.
@Controller
@RequestMapping("/braintree")
public class BraintreePaymentService {
@Autowired
private RestaurantRepository restaurantRepository;
@Autowired
private OrderRepository orderRepository;
private WeakHashMap<String, BraintreeGateway> gatewayCache = new WeakHashMap<>();
private BraintreeGateway getGateway(String auth) {
BraintreeGateway bg = gatewayCache.get(auth);
if(bg != null) {
return bg;
}
RestaurantEntity r = restaurantRepository.findOne(auth);
if(r != null) {
bg = new BraintreeGateway(
Environment.SANDBOX,
r.getMerchantId(),
r.getPublicKey(),
r.getPrivateKey()
);
gatewayCache.put(auth, bg);
return bg;
}
return null;
}
BraintreePaymentService
Notice that the normal braintree API hardcodes all of these values but we load them dynamically and then place them in a cache for reuse. The reason for this is that the
braintree credentials are specific to restaurant and we will have multiple restaurants running on a single server
@RequestMapping(method=RequestMethod.GET)
public @ResponseBody String getToken(@RequestParam(name = "auth") String auth) {
return getGateway(auth).clientToken().generate();
}
@RequestMapping(method=RequestMethod.POST)
public @ResponseBody PurchaseResult purchase(@RequestBody(required=true) Order i) {
TransactionRequest request = new TransactionRequest()
.amount(i.calculateAmount())
.paymentMethodNonce(i.getNounce())
.options()
.submitForSettlement(true)
.done();
Result<Transaction> result = getGateway(i.getAuth()).transaction().sale(request);
if(result.isSuccess()) {
// Store entry and email restaurant
}
return new PurchaseResult(result.isSuccess(), result.getMessage());
}
}
BraintreePaymentService
The service methods themselves are pretty trivial
@RequestMapping(method=RequestMethod.GET)
public @ResponseBody String getToken(@RequestParam(name = "auth") String auth) {
return getGateway(auth).clientToken().generate();
}
@RequestMapping(method=RequestMethod.POST)
public @ResponseBody PurchaseResult purchase(@RequestBody(required=true) Order i) {
TransactionRequest request = new TransactionRequest()
.amount(i.calculateAmount())
.paymentMethodNonce(i.getNounce())
.options()
.submitForSettlement(true)
.done();
Result<Transaction> result = getGateway(i.getAuth()).transaction().sale(request);
if(result.isSuccess()) {
// Store entry and email restaurant
}
return new PurchaseResult(result.isSuccess(), result.getMessage());
}
}
BraintreePaymentService
The token is generated using the standard braintree API, there isn’t much here it just returns the string which we use in the client side code
@RequestMapping(method=RequestMethod.GET)
public @ResponseBody String getToken(@RequestParam(name = "auth") String auth) {
return getGateway(auth).clientToken().generate();
}
@RequestMapping(method=RequestMethod.POST)
public @ResponseBody PurchaseResult purchase(@RequestBody(required=true) Order i) {
TransactionRequest request = new TransactionRequest()
.amount(i.calculateAmount())
.paymentMethodNonce(i.getNounce())
.options()
.submitForSettlement(true)
.done();
Result<Transaction> result = getGateway(i.getAuth()).transaction().sale(request);
if(result.isSuccess()) {
// Store entry and email restaurant
}
return new PurchaseResult(result.isSuccess(), result.getMessage());
}
}
BraintreePaymentService
The interesting method is the purchase method where we create a purchase request and finally fill in the amount we want to pay.

This isn’t obvious from the code here but we have a small security issue in this code…
@RequestMapping(method=RequestMethod.GET)
public @ResponseBody String getToken(@RequestParam(name = "auth") String auth) {
return getGateway(auth).clientToken().generate();
}
@RequestMapping(method=RequestMethod.POST)
public @ResponseBody PurchaseResult purchase(@RequestBody(required=true) Order i) {
TransactionRequest request = new TransactionRequest()
.amount(i.calculateAmount())
.paymentMethodNonce(i.getNounce())
.options()
.submitForSettlement(true)
.done();
Result<Transaction> result = getGateway(i.getAuth()).transaction().sale(request);
if(result.isSuccess()) {
// Store entry and email restaurant
}
return new PurchaseResult(result.isSuccess(), result.getMessage());
}
}
BraintreePaymentService
Right here… Calculate amount runs on the order which we received from the client. This means that the prices of the elements in the order were also received from the
client.

Our client is theoretically trustworthy but if someone reverse engineers the communication protocol or the client they could just change the prices of the dishes to give
themselves a discount. However, if we just take the dish ID and calculate the price on the server this will make no difference…

This doesn’t even have to be malicious, if a price was updated and a local copy of the app still has the old price because a user hasn’t launched the app in a year. It’s
important to make these calculations in the server always. In the final version of the server this is fixed but I kept it for now in the interest of simplicity and also to
demonstrate how nuanced security issues can be.
@Entity
@Table(name="Restaurant")
public class RestaurantEntity {
@Id
private String id;
private String name;
private String merchantId;
private String publicKey;
private String privateKey;
private double currentVersionIOS = 1.0;
private double lastSupportedVersionIOS = 0;
private double currentVersionAnd = 1.0;
private double lastSupportedVersionAnd = 0;
private double currentVersionUWP = 1.0;
private double lastSupportedVersionUWP = 0;
private long dishListUpdateTimestamp = 1;
private String restaurantEmail;
@OneToMany
private Set<DishEntity> dishes;
@OneToMany
private Set<CategoryEntity> categories;
public RestaurantEntity() {
id = UUID.randomUUID().toString();
}
RestaurantEntity
This is the basic restaurant entity. It allows us to save the details we need of the restaurant. We’ll add a lot more into this class but for now all we need are these things. 

Notice that instead of using a numeric auto generated id I chose to use a string which I’ve set to a universal unique identifier in the constructor. 

Numeric id’s are sometimes problematic as one can potentially guess the id’s and scan your database. E.g. if someone notices that we have an API called listDishes that
accepts the restaurant id this might be a problem. He could scrape the API for all the dishes of all the restaurants by scanning integer values.

Scanning UUID values will take centuries or even eons.
@Entity
@Table(name="Purchases")
public class OrderEntity {
@Id
private String id;
@OneToMany
private Set<OrderLineEntity> dishQuanity;
private Date date;
private String notes;
public OrderEntity() {
id = UUID.randomUUID().toString();
}
OrderEntity vs. dao Order
public class Order {
private String id;
private Date date;
private boolean purchased;
private Map<Dish, Integer> dishQuantity = new
HashMap<>();
private String notes;
private String nounce;
private String auth;
public BigDecimal calculateAmount() {
BigDecimal b = BigDecimal.ZERO;
for(Map.Entry<Dish, Integer> d :
dishQuantity.entrySet()) {
b = b.add(new BigDecimal(
d.getValue() *
d.getKey().
getPrice()));
}
return b;
}
When looking at the code you will see some duplication. In this example we can see the order entity next to the order DAO. 

You will notice that these values are very similar to one another, a DAO transfers data from the client or within the server and an entity stores the data. They are often
mirror images of one another but not always. In this case we can see that the DAO contains things that aren’t a part of the order.

Also the structure is different since the entity needs to map to storage structure and the DAO is designed for our convenience. This is a common practice that saves the
need to pass entities around and break the separation of the tiers within the application. It allows us to have some flexibility with our data.
@Controller
@RequestMapping("/ver")
public class VersionService {
@Autowired
private RestaurantRepository restaurantRepository;
@RequestMapping(method=RequestMethod.GET)
public @ResponseBody AppVersion getKey(@RequestParam(value="os", required=true) String os,
@RequestParam(value="appId", required=true) String appId) {
RestaurantEntity r = restaurantRepository.findOne(appId);
switch(os) {
case "ios":
return new AppVersion(r.getCurrentVersionIOS(), r.getLastSupportedVersionIOS());
case "and":
return new AppVersion(r.getCurrentVersionAnd(), r.getLastSupportedVersionAnd());
case "win":
return new AppVersion(r.getCurrentVersionUWP(), r.getLastSupportedVersionUWP());
}
return null;
}
}
VersionService
The versioning service allows us to detect if a new version of the app is available and effectively allows us to disable outdated versions. This is important as we might be
stuck with an out of date protocol that we wish to retire or we might need to change the server address.
Thank You
Thanks for watching. I hope you found this informative

More Related Content

Similar to Restaurant Server - Transcript.pdf

Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and Symfony
Ignacio Martín
 
Esposito Ajax Remote
Esposito Ajax RemoteEsposito Ajax Remote
Esposito Ajax Remoteask bills
 
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense SolutionsSpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
VMware Tanzu
 
How to perform debounce in react
How to perform debounce in reactHow to perform debounce in react
How to perform debounce in react
BOSC Tech Labs
 
Jakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testyJakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testy
Paweł Tekliński
 
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Fwdays
 
Angular resolver tutorial
Angular resolver tutorialAngular resolver tutorial
Angular resolver tutorial
Katy Slemon
 
Testing C# and ASP.net using Ruby
Testing C# and ASP.net using RubyTesting C# and ASP.net using Ruby
Testing C# and ASP.net using Ruby
Ben Hall
 
Itb 2021 - Bulding Quick APIs by Gavin Pickin
Itb 2021 - Bulding Quick APIs by Gavin PickinItb 2021 - Bulding Quick APIs by Gavin Pickin
Itb 2021 - Bulding Quick APIs by Gavin Pickin
Gavin Pickin
 
Apache Aries Blog Sample
Apache Aries Blog SampleApache Aries Blog Sample
Apache Aries Blog Sample
Skills Matter
 
WCF - In a Week
WCF - In a WeekWCF - In a Week
WCF - In a Week
gnanaarunganesh
 
Salesforce and sap integration
Salesforce and sap integrationSalesforce and sap integration
Salesforce and sap integration
Karanraj Sankaranarayanan
 
REST API for your WP7 App
REST API for your WP7 AppREST API for your WP7 App
REST API for your WP7 App
Agnius Paradnikas
 
Testing ASP.net Web Applications using Ruby
Testing ASP.net Web Applications using RubyTesting ASP.net Web Applications using Ruby
Testing ASP.net Web Applications using Ruby
Ben Hall
 
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
Rob Tweed
 
Server Side Swift - AppBuilders 2017
Server Side Swift - AppBuilders 2017Server Side Swift - AppBuilders 2017
Server Side Swift - AppBuilders 2017
Jens Ravens
 
Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right way
Thibaud Desodt
 
ATAGTR2017 CDC Tests - Integration Tests cant be made simpler than this!
ATAGTR2017 CDC Tests - Integration Tests cant be made simpler than this!ATAGTR2017 CDC Tests - Integration Tests cant be made simpler than this!
ATAGTR2017 CDC Tests - Integration Tests cant be made simpler than this!
Agile Testing Alliance
 
Data models in Angular 1 & 2
Data models in Angular 1 & 2Data models in Angular 1 & 2
Data models in Angular 1 & 2
Adam Klein
 
Creating an Uber Clone - Part XXXI - Transcript.pdf
Creating an Uber Clone - Part XXXI - Transcript.pdfCreating an Uber Clone - Part XXXI - Transcript.pdf
Creating an Uber Clone - Part XXXI - Transcript.pdf
ShaiAlmog1
 

Similar to Restaurant Server - Transcript.pdf (20)

Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and Symfony
 
Esposito Ajax Remote
Esposito Ajax RemoteEsposito Ajax Remote
Esposito Ajax Remote
 
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense SolutionsSpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
 
How to perform debounce in react
How to perform debounce in reactHow to perform debounce in react
How to perform debounce in react
 
Jakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testyJakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testy
 
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
 
Angular resolver tutorial
Angular resolver tutorialAngular resolver tutorial
Angular resolver tutorial
 
Testing C# and ASP.net using Ruby
Testing C# and ASP.net using RubyTesting C# and ASP.net using Ruby
Testing C# and ASP.net using Ruby
 
Itb 2021 - Bulding Quick APIs by Gavin Pickin
Itb 2021 - Bulding Quick APIs by Gavin PickinItb 2021 - Bulding Quick APIs by Gavin Pickin
Itb 2021 - Bulding Quick APIs by Gavin Pickin
 
Apache Aries Blog Sample
Apache Aries Blog SampleApache Aries Blog Sample
Apache Aries Blog Sample
 
WCF - In a Week
WCF - In a WeekWCF - In a Week
WCF - In a Week
 
Salesforce and sap integration
Salesforce and sap integrationSalesforce and sap integration
Salesforce and sap integration
 
REST API for your WP7 App
REST API for your WP7 AppREST API for your WP7 App
REST API for your WP7 App
 
Testing ASP.net Web Applications using Ruby
Testing ASP.net Web Applications using RubyTesting ASP.net Web Applications using Ruby
Testing ASP.net Web Applications using Ruby
 
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
 
Server Side Swift - AppBuilders 2017
Server Side Swift - AppBuilders 2017Server Side Swift - AppBuilders 2017
Server Side Swift - AppBuilders 2017
 
Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right way
 
ATAGTR2017 CDC Tests - Integration Tests cant be made simpler than this!
ATAGTR2017 CDC Tests - Integration Tests cant be made simpler than this!ATAGTR2017 CDC Tests - Integration Tests cant be made simpler than this!
ATAGTR2017 CDC Tests - Integration Tests cant be made simpler than this!
 
Data models in Angular 1 & 2
Data models in Angular 1 & 2Data models in Angular 1 & 2
Data models in Angular 1 & 2
 
Creating an Uber Clone - Part XXXI - Transcript.pdf
Creating an Uber Clone - Part XXXI - Transcript.pdfCreating an Uber Clone - Part XXXI - Transcript.pdf
Creating an Uber Clone - Part XXXI - Transcript.pdf
 

More from ShaiAlmog1

The Duck Teaches Learn to debug from the masters. Local to production- kill ...
The Duck Teaches  Learn to debug from the masters. Local to production- kill ...The Duck Teaches  Learn to debug from the masters. Local to production- kill ...
The Duck Teaches Learn to debug from the masters. Local to production- kill ...
ShaiAlmog1
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdf
ShaiAlmog1
 
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfcreate-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdf
ShaiAlmog1
 
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfcreate-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdf
ShaiAlmog1
 
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfcreate-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdf
ShaiAlmog1
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdf
ShaiAlmog1
 
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfcreate-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdf
ShaiAlmog1
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdf
ShaiAlmog1
 
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfcreate-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdf
ShaiAlmog1
 
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfcreate-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdf
ShaiAlmog1
 
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfcreate-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdf
ShaiAlmog1
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdf
ShaiAlmog1
 
create-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfcreate-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdf
ShaiAlmog1
 
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfCreating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdf
ShaiAlmog1
 
Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfCreating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdf
ShaiAlmog1
 
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfCreating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdf
ShaiAlmog1
 
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfCreating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdf
ShaiAlmog1
 
Creating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfCreating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdf
ShaiAlmog1
 
Creating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfCreating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdf
ShaiAlmog1
 
Creating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfCreating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdf
ShaiAlmog1
 

More from ShaiAlmog1 (20)

The Duck Teaches Learn to debug from the masters. Local to production- kill ...
The Duck Teaches  Learn to debug from the masters. Local to production- kill ...The Duck Teaches  Learn to debug from the masters. Local to production- kill ...
The Duck Teaches Learn to debug from the masters. Local to production- kill ...
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdf
 
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfcreate-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdf
 
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfcreate-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdf
 
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfcreate-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdf
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdf
 
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfcreate-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdf
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdf
 
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfcreate-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdf
 
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfcreate-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdf
 
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfcreate-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdf
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdf
 
create-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfcreate-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdf
 
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfCreating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdf
 
Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfCreating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdf
 
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfCreating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdf
 
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfCreating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdf
 
Creating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfCreating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdf
 
Creating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfCreating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdf
 
Creating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfCreating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdf
 

Recently uploaded

Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
CatarinaPereira64715
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
Abida Shariff
 

Recently uploaded (20)

Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 

Restaurant Server - Transcript.pdf

  • 1. Restaurant Server I skipped the server creation tutorial before as I felt it left the domain of Codename One too much and ventured into server programming. In this level we don’t skip such things so I’m going to review the server code related to the restaurant app and why it was built like that.
  • 2. Restaurant Server ✦ I will not go into all of the details because many pieces are mundane and boring ✦ The server portion is relatively easier when we have a client ready but there is a lot of hidden complexity ✦ This is especially true when it comes to security which is often unintuitive © Codename One 2017 all rights reserved I find server programming to be boring. That’s not a bad thing, boring can be great when you need something you can rely on which is exactly what a good server should be. I’ll try to focus on the interesting pieces only and I won’t even mention some of the entities or their relations as they are just “more of the same”. There are some great Java EE and Spring Boot courses out there and I don’t think it’s our place to displace them. Because we did the client first the server portion is mostly filling in the blanks, there are still some hidden complex nuggets but it’s mostly simple. Security is one of the more challenging things about server programming, I’ll try to explain as much as I can but once you go into security there is always more to know… It’s a specialty in its own right.
  • 3. Standard Spring Boot project ✦We’ll create pretty much the same spring boot project we created in the spring boot tutorial ✦I’ll go with a new Database URL to start fresh and new project name “AppBackendServer”. The generic name makes sense for the app maker… ✦My goal isn’t to win an “architecture award” but to create the bare minimum server within reason © Codename One 2017 all rights reserved Our starting point will be the same spring boot project I did in the base course. I’ll use mysql again and create a blank database. We’ll use app backend server as the project name. The same database & project will be used for the app maker as well as the app itself. There are some nuances in Spring such as service components which are similar to sessions beans in Java EE. I’m not using any of those things which would make sense in an architectural standpoint but aren’t really useful for our narrow use case.
  • 4. <dependency> <groupId>com.braintreepayments.gateway</groupId> <artifactId>braintree-java</artifactId> <version>2.71.0</version> </dependency> BrainTree Support - pom.xml Lets start right away, assuming the project was created adding braintree support to the server side starts with editing the pom file with the right dependency. This will allow us to compile the code that supports braintree
  • 5. @Controller @RequestMapping("/braintree") public class BraintreePaymentService { @Autowired private RestaurantRepository restaurantRepository; @Autowired private OrderRepository orderRepository; private WeakHashMap<String, BraintreeGateway> gatewayCache = new WeakHashMap<>(); private BraintreeGateway getGateway(String auth) { BraintreeGateway bg = gatewayCache.get(auth); if(bg != null) { return bg; } RestaurantEntity r = restaurantRepository.findOne(auth); if(r != null) { bg = new BraintreeGateway( Environment.SANDBOX, r.getMerchantId(), r.getPublicKey(), r.getPrivateKey() ); gatewayCache.put(auth, bg); return bg; } return null; } BraintreePaymentService The braintree service is pretty simple, it maps to the braintree URL. The first thing we do is provide access to the braintree gateway.
  • 6. @Controller @RequestMapping("/braintree") public class BraintreePaymentService { @Autowired private RestaurantRepository restaurantRepository; @Autowired private OrderRepository orderRepository; private WeakHashMap<String, BraintreeGateway> gatewayCache = new WeakHashMap<>(); private BraintreeGateway getGateway(String auth) { BraintreeGateway bg = gatewayCache.get(auth); if(bg != null) { return bg; } RestaurantEntity r = restaurantRepository.findOne(auth); if(r != null) { bg = new BraintreeGateway( Environment.SANDBOX, r.getMerchantId(), r.getPublicKey(), r.getPrivateKey() ); gatewayCache.put(auth, bg); return bg; } return null; } BraintreePaymentService Notice that the normal braintree API hardcodes all of these values but we load them dynamically and then place them in a cache for reuse. The reason for this is that the braintree credentials are specific to restaurant and we will have multiple restaurants running on a single server
  • 7. @RequestMapping(method=RequestMethod.GET) public @ResponseBody String getToken(@RequestParam(name = "auth") String auth) { return getGateway(auth).clientToken().generate(); } @RequestMapping(method=RequestMethod.POST) public @ResponseBody PurchaseResult purchase(@RequestBody(required=true) Order i) { TransactionRequest request = new TransactionRequest() .amount(i.calculateAmount()) .paymentMethodNonce(i.getNounce()) .options() .submitForSettlement(true) .done(); Result<Transaction> result = getGateway(i.getAuth()).transaction().sale(request); if(result.isSuccess()) { // Store entry and email restaurant } return new PurchaseResult(result.isSuccess(), result.getMessage()); } } BraintreePaymentService The service methods themselves are pretty trivial
  • 8. @RequestMapping(method=RequestMethod.GET) public @ResponseBody String getToken(@RequestParam(name = "auth") String auth) { return getGateway(auth).clientToken().generate(); } @RequestMapping(method=RequestMethod.POST) public @ResponseBody PurchaseResult purchase(@RequestBody(required=true) Order i) { TransactionRequest request = new TransactionRequest() .amount(i.calculateAmount()) .paymentMethodNonce(i.getNounce()) .options() .submitForSettlement(true) .done(); Result<Transaction> result = getGateway(i.getAuth()).transaction().sale(request); if(result.isSuccess()) { // Store entry and email restaurant } return new PurchaseResult(result.isSuccess(), result.getMessage()); } } BraintreePaymentService The token is generated using the standard braintree API, there isn’t much here it just returns the string which we use in the client side code
  • 9. @RequestMapping(method=RequestMethod.GET) public @ResponseBody String getToken(@RequestParam(name = "auth") String auth) { return getGateway(auth).clientToken().generate(); } @RequestMapping(method=RequestMethod.POST) public @ResponseBody PurchaseResult purchase(@RequestBody(required=true) Order i) { TransactionRequest request = new TransactionRequest() .amount(i.calculateAmount()) .paymentMethodNonce(i.getNounce()) .options() .submitForSettlement(true) .done(); Result<Transaction> result = getGateway(i.getAuth()).transaction().sale(request); if(result.isSuccess()) { // Store entry and email restaurant } return new PurchaseResult(result.isSuccess(), result.getMessage()); } } BraintreePaymentService The interesting method is the purchase method where we create a purchase request and finally fill in the amount we want to pay. This isn’t obvious from the code here but we have a small security issue in this code…
  • 10. @RequestMapping(method=RequestMethod.GET) public @ResponseBody String getToken(@RequestParam(name = "auth") String auth) { return getGateway(auth).clientToken().generate(); } @RequestMapping(method=RequestMethod.POST) public @ResponseBody PurchaseResult purchase(@RequestBody(required=true) Order i) { TransactionRequest request = new TransactionRequest() .amount(i.calculateAmount()) .paymentMethodNonce(i.getNounce()) .options() .submitForSettlement(true) .done(); Result<Transaction> result = getGateway(i.getAuth()).transaction().sale(request); if(result.isSuccess()) { // Store entry and email restaurant } return new PurchaseResult(result.isSuccess(), result.getMessage()); } } BraintreePaymentService Right here… Calculate amount runs on the order which we received from the client. This means that the prices of the elements in the order were also received from the client. Our client is theoretically trustworthy but if someone reverse engineers the communication protocol or the client they could just change the prices of the dishes to give themselves a discount. However, if we just take the dish ID and calculate the price on the server this will make no difference… This doesn’t even have to be malicious, if a price was updated and a local copy of the app still has the old price because a user hasn’t launched the app in a year. It’s important to make these calculations in the server always. In the final version of the server this is fixed but I kept it for now in the interest of simplicity and also to demonstrate how nuanced security issues can be.
  • 11. @Entity @Table(name="Restaurant") public class RestaurantEntity { @Id private String id; private String name; private String merchantId; private String publicKey; private String privateKey; private double currentVersionIOS = 1.0; private double lastSupportedVersionIOS = 0; private double currentVersionAnd = 1.0; private double lastSupportedVersionAnd = 0; private double currentVersionUWP = 1.0; private double lastSupportedVersionUWP = 0; private long dishListUpdateTimestamp = 1; private String restaurantEmail; @OneToMany private Set<DishEntity> dishes; @OneToMany private Set<CategoryEntity> categories; public RestaurantEntity() { id = UUID.randomUUID().toString(); } RestaurantEntity This is the basic restaurant entity. It allows us to save the details we need of the restaurant. We’ll add a lot more into this class but for now all we need are these things. Notice that instead of using a numeric auto generated id I chose to use a string which I’ve set to a universal unique identifier in the constructor. Numeric id’s are sometimes problematic as one can potentially guess the id’s and scan your database. E.g. if someone notices that we have an API called listDishes that accepts the restaurant id this might be a problem. He could scrape the API for all the dishes of all the restaurants by scanning integer values. Scanning UUID values will take centuries or even eons.
  • 12. @Entity @Table(name="Purchases") public class OrderEntity { @Id private String id; @OneToMany private Set<OrderLineEntity> dishQuanity; private Date date; private String notes; public OrderEntity() { id = UUID.randomUUID().toString(); } OrderEntity vs. dao Order public class Order { private String id; private Date date; private boolean purchased; private Map<Dish, Integer> dishQuantity = new HashMap<>(); private String notes; private String nounce; private String auth; public BigDecimal calculateAmount() { BigDecimal b = BigDecimal.ZERO; for(Map.Entry<Dish, Integer> d : dishQuantity.entrySet()) { b = b.add(new BigDecimal( d.getValue() * d.getKey(). getPrice())); } return b; } When looking at the code you will see some duplication. In this example we can see the order entity next to the order DAO. You will notice that these values are very similar to one another, a DAO transfers data from the client or within the server and an entity stores the data. They are often mirror images of one another but not always. In this case we can see that the DAO contains things that aren’t a part of the order. Also the structure is different since the entity needs to map to storage structure and the DAO is designed for our convenience. This is a common practice that saves the need to pass entities around and break the separation of the tiers within the application. It allows us to have some flexibility with our data.
  • 13. @Controller @RequestMapping("/ver") public class VersionService { @Autowired private RestaurantRepository restaurantRepository; @RequestMapping(method=RequestMethod.GET) public @ResponseBody AppVersion getKey(@RequestParam(value="os", required=true) String os, @RequestParam(value="appId", required=true) String appId) { RestaurantEntity r = restaurantRepository.findOne(appId); switch(os) { case "ios": return new AppVersion(r.getCurrentVersionIOS(), r.getLastSupportedVersionIOS()); case "and": return new AppVersion(r.getCurrentVersionAnd(), r.getLastSupportedVersionAnd()); case "win": return new AppVersion(r.getCurrentVersionUWP(), r.getLastSupportedVersionUWP()); } return null; } } VersionService The versioning service allows us to detect if a new version of the app is available and effectively allows us to disable outdated versions. This is important as we might be stuck with an out of date protocol that we wish to retire or we might need to change the server address.
  • 14. Thank You Thanks for watching. I hope you found this informative