SlideShare a Scribd company logo
1 of 55
Download to read offline
Rest.li
Development Workflow Overview
Joe Betz, April 2014
Let’s implement a Simple REST request
Let’s implement a Simple REST request
GET /fortunes/1 HTTP/1.1
Accept: application/json
Request
Let’s implement a Simple REST request
GET /fortunes/1 HTTP/1.1
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: …
!
{
"message": "Today’s your lucky day!"
}
Request Response
Step 1. Write a Data Schema
Step 1. Write a Data Schema
Fortune.pdsc
{
"name" : "Fortune",
"namespace" : "com.example",
"type" : "record",
"fields" : [
{ "name" : "message", "type" : "string" }
]
}
Step 1. Write a Data Schema
Fortune.pdsc
{
"name" : "Fortune",
"namespace" : "com.example",
"type" : "record",
"fields" : [
{ "name" : "message", "type" : "string" }
]
}
This schema defines a Fortune record. It has
a single message field of type string. Rest.li
schemas are based on avro schemas, and
supports maps, lists, optional fields, unions and
other useful data modeling constructs.
Step 1. Write a Data Schema
Fortune.pdsc
{
"name" : "Fortune",
"namespace" : "com.example",
"type" : "record",
"fields" : [
{ "name" : "message", "type" : "string" }
]
}
Rest.li schemas are designed for JSON. Here’s
what a Fortune looks like in JSON:
{
“message”: “Today is your lucky day!”
}
Step 1. Write a Data Schema
Fortune.pdsc
{
"name" : "Fortune",
"namespace" : "com.example",
"type" : "record",
"fields" : [
{ "name" : "message", "type" : "string" }
]
}
Rest.li’s automatically generates a binding class from our data schema:
Step 1. Write a Data Schema
Fortune.pdsc
{
"name" : "Fortune",
"namespace" : "com.example",
"type" : "record",
"fields" : [
{ "name" : "message", "type" : "string" }
]
}
Fortune.java
public class Fortune extends
RecordTemplate {
String getMessage();
void setMessage(String);
}
Rest.li’s automatically generates a binding class from our data schema:
Generated
Code
Step 1. Write a Data Schema
Fortune.pdsc
{
"name" : "Fortune",
"namespace" : "com.example",
"type" : "record",
"fields" : [
{ "name" : "message", "type" : "string" }
]
}
Fortune.java
public class Fortune extends
RecordTemplate {
String getMessage();
void setMessage(String);
}
Rest.li’s automatically generates a binding class from our data schema:
Generated
Code
This class is important, we’ll use it in a minute.
Step 2. Write a REST Resource
FortunesResource.java
@RestLiCollection(name = "fortunes")
class FortunesResource implements KeyValueResource<Long, Fortune> {
!
@RestMethod.GET
public Fortune get(Long key) {
return new Fortune()
.setMessage("Today’s your lucky day!");
}
}
Step 2. Write a REST Resource
FortunesResource.java
@RestLiCollection(name = "fortunes")
class FortunesResource implements KeyValueResource<Long, Fortune> {
!
@RestMethod.GET
public Fortune get(Long key) {
return new Fortune()
.setMessage("Today’s your lucky day!");
}
}
Step 2. Write a REST Resource
Rest.li annotation declares this class as our
implementation of the /fortunes resource.
FortunesResource.java
@RestLiCollection(name = "fortunes")
class FortunesResource implements KeyValueResource<Long, Fortune> {
!
@RestMethod.GET
public Fortune get(Long key) {
return new Fortune()
.setMessage("Today’s your lucky day!");
}
}
Step 2. Write a REST Resource
Our collection contains
Fortune entities, keyed by
Long.
FortunesResource.java
@RestLiCollection(name = "fortunes")
class FortunesResource implements KeyValueResource<Long, Fortune> {
!
@RestMethod.GET
public Fortune get(Long key) {
return new Fortune()
.setMessage("Today’s your lucky day!");
}
}
Step 2. Write a REST Resource
Our collection contains
Fortune entities, keyed by
Long.
Notice how we use the
generated Fortune class
here so everything is strongly
typed.
FortunesResource.java
@RestLiCollection(name = "fortunes")
class FortunesResource implements KeyValueResource<Long, Fortune> {
!
@RestMethod.GET
public Fortune get(Long key) {
return new Fortune()
.setMessage("Today’s your lucky day!");
}
}
Step 2. Write a REST Resource
Here we implement HTTP GET
FortunesResource.java
@RestLiCollection(name = "fortunes")
class FortunesResource implements KeyValueResource<Long, Fortune> {
!
@RestMethod.GET
public Fortune get(Long key) {
return new Fortune()
.setMessage("Today’s your lucky day!");
}
}
Step 2. Write a REST Resource
From our resource implementation,
Rest.li’s automatically generates an interface definition,
FortunesResource.java
@RestLiCollection(name = "fortunes")
class FortunesResource implements KeyValueResource<Long, Fortune> {
!
@RestMethod.GET
public Fortune get(Long key) {
return new Fortune()
.setMessage("Today’s your lucky day!");
}
}
Step 2. Write a REST Resource
fortunes.restspec.json
{
“path”: “/fortunes”,
“supports”: [ “get” ],
…
}
From our resource implementation,
Rest.li’s automatically generates an interface definition,
Generated
Code
FortunesResource.java
@RestLiCollection(name = "fortunes")
class FortunesResource implements KeyValueResource<Long, Fortune> {
!
@RestMethod.GET
public Fortune get(Long key) {
return new Fortune()
.setMessage("Today’s your lucky day!");
}
}
Step 2. Write a REST Resource
fortunes.restspec.json
{
“path”: “/fortunes”,
“supports”: [ “get” ],
…
}
From our resource implementation,
Rest.li’s automatically generates an interface definition, and client bindings.
Generated
Code
FortunesResource.java
@RestLiCollection(name = "fortunes")
class FortunesResource implements KeyValueResource<Long, Fortune> {
!
@RestMethod.GET
public Fortune get(Long key) {
return new Fortune()
.setMessage("Today’s your lucky day!");
}
}
Step 2. Write a REST Resource
FortunesBuilders.java
public class FortunesBuilders {
GetRequestBuilder get();
}
fortunes.restspec.json
{
“path”: “/fortunes”,
“supports”: [ “get” ],
…
}
From our resource implementation,
Rest.li’s automatically generates an interface definition, and client bindings.
Generated
Code Generated
Code
FortunesResource.java
@RestLiCollection(name = "fortunes")
class FortunesResource implements KeyValueResource<Long, Fortune> {
!
@RestMethod.GET
public Fortune get(Long key) {
return new Fortune()
.setMessage("Today’s your lucky day!");
}
}
Step 2. Write a REST Resource
FortunesBuilders.java
public class FortunesBuilders {
GetRequestBuilder get();
}
fortunes.restspec.json
{
“path”: “/fortunes”,
“supports”: [ “get” ],
…
}
From our resource implementation,
Rest.li’s automatically generates an interface definition, and client bindings.
Generated
Code Generated
Code
We’ll use these to build our client.
Step 3. Write a Client
Step 3. Write a Client
ExampleClient.java
Response response = restClient.sendRequest(new FortunesBuilders.get().id(1L)).get();
Fortune fortune = response.getEntity();
System.out.println(fortune.getMessage());
Step 3. Write a Client
ExampleClient.java
Response response = restClient.sendRequest(new FortunesBuilders.get().id(1L)).get();
Fortune fortune = response.getEntity();
System.out.println(fortune.getMessage());
We use client bindings generated
from our /fortune resource to build
an HTTP GET Request.
Step 3. Write a Client
ExampleClient.java
Response response = restClient.sendRequest(new FortunesBuilders.get().id(1L)).get();
Fortune fortune = response.getEntity();
System.out.println(fortune.getMessage());
We use client bindings generated
from our /fortune resource to build
an HTTP GET Request.
And we use the Rest.li RestClient to
send the request.
Step 3. Write a Client
ExampleClient.java
Response response = restClient.sendRequest(new FortunesBuilders.get().id(1L)).get();
Fortune fortune = response.getEntity();
System.out.println(fortune.getMessage());
We use client bindings generated
from our /fortune resource to build
an HTTP GET Request.
And we use the Rest.li RestClient to
send the request.
Notice how everything is strongly typed.
Step 3. Write a Client
ExampleClient.java
Response response = restClient.sendRequest(new FortunesBuilders.get().id(1L)).get();
Fortune fortune = response.getEntity();
System.out.println(fortune.getMessage());
We use client bindings generated
from our /fortune resource to build
an HTTP GET Request.
And we use the Rest.li RestClient to
send the request.
Notice how everything is strongly typed.
But wait, this request is blocking! The .get() forces the
thread block and wait for a response from the server. We’ll
show how to make this non-blocking shortly.
Step 4. Run it!
Step 4. Run it!
“Today’s your lucky day!”
Step 4. Run it!
“Today’s your lucky day!”
Great! but all our code is synchronous and blocking. What about non-blocking?
Importance of async, non-blocking request
handling
Importance of async, non-blocking request
handling
Async processing is ideal for making multiple requests to backend systems in parallel and then
composing the results of those parallel requests into a single response. For modern internet
architectures, where many backend systems are involved in handling each request from a consumer,
making calls in parallel to these backend systems dramatically reduces the overall time to response
back to the consumer.
Importance of async, non-blocking request
handling
Async processing is ideal for making multiple requests to backend systems in parallel and then
composing the results of those parallel requests into a single response. For modern internet
architectures, where many backend systems are involved in handling each request from a consumer,
making calls in parallel to these backend systems dramatically reduces the overall time to response
back to the consumer.
Servers running async code scale better because they can handle very large numbers of
concurrent requests. This is because, when you write async code, no threads are blocked waiting
for something to complete. If you don’t write async code and you need to handle large numbers of
concurrent requests, you’ll need one thread per concurrent request. Each thread takes up
considerable memory, and when you run out of memory (or max out a thread pool), the server is
unable to take on more requests, resulting in timed out requests and in cases of many complex
architectures, cascading failure.
Async in Rest.li
Async in Rest.li
Rest.li integrates with ParSeq for both client and server side
async.
Async in Rest.li
Rest.li integrates with ParSeq for both client and server side
async.
Using ParSeq, we will write Tasks. Tasks can be composed
together in parallel (par) or sequence (seq) into larger tasks.
Tasks are executed asynchronously by the ParSeq engine.
Async in Rest.li
Rest.li integrates with ParSeq for both client and server side
async.
Using ParSeq, we will write Tasks. Tasks can be composed
together in parallel (par) or sequence (seq) into larger tasks.
Tasks are executed asynchronously by the ParSeq engine.
Let’s modify our Resource Implementation and Client to use
ParSeq.
Async Resource Implementation
Async Resource Implementation
FortunesResource.java
@RestLiCollection(name = "fortunes")
class FortunesResource
implements KeyValueResource<Integer, Fortune> {
!
@RestMethod.GET
public Task<Fortune> get(Long key) {
Task<String> retrieveFortuneStr = … ;
!
Task<Fortune> buildFortune =
Tasks.action("getFortune", new Callable<Fortune>() {
@Override public Fortune call() throws Exception {
return new Fortune()
.setMessage(retieveFortuneStr.get());
}
});
return Tasks.seq(retrieveFortuneStr, buildFortune);
}
}
Async Resource Implementation
FortunesResource.java
@RestLiCollection(name = "fortunes")
class FortunesResource
implements KeyValueResource<Integer, Fortune> {
!
@RestMethod.GET
public Task<Fortune> get(Long key) {
Task<String> retrieveFortuneStr = … ;
!
Task<Fortune> buildFortune =
Tasks.action("getFortune", new Callable<Fortune>() {
@Override public Fortune call() throws Exception {
return new Fortune()
.setMessage(retieveFortuneStr.get());
}
});
return Tasks.seq(retrieveFortuneStr, buildFortune);
}
}
Rest.li resources methods can
return a ParSeq Task. Rest.li will
execute them asynchronously
and respond with the result when
it’s available.
Async Resource Implementation
FortunesResource.java
@RestLiCollection(name = "fortunes")
class FortunesResource
implements KeyValueResource<Integer, Fortune> {
!
@RestMethod.GET
public Task<Fortune> get(Long key) {
Task<String> retrieveFortuneStr = … ;
!
Task<Fortune> buildFortune =
Tasks.action("getFortune", new Callable<Fortune>() {
@Override public Fortune call() throws Exception {
return new Fortune()
.setMessage(retieveFortuneStr.get());
}
});
return Tasks.seq(retrieveFortuneStr, buildFortune);
}
}
Here we compose together
two tasks together in
sequence using Tasks.seq
Async Resource Implementation
FortunesResource.java
@RestLiCollection(name = "fortunes")
class FortunesResource
implements KeyValueResource<Integer, Fortune> {
!
@RestMethod.GET
public Task<Fortune> get(Long key) {
Task<String> retrieveFortuneStr = … ;
!
Task<Fortune> buildFortune =
Tasks.action("getFortune", new Callable<Fortune>() {
@Override public Fortune call() throws Exception {
return new Fortune()
.setMessage(retieveFortuneStr.get());
}
});
return Tasks.seq(retrieveFortuneStr, buildFortune);
}
}
Here we compose together
two tasks together in
sequence using Tasks.seq
The retrieveFortuneStr task is
a non-blocking IO task to get a
fortune string.
Async Resource Implementation
FortunesResource.java
@RestLiCollection(name = "fortunes")
class FortunesResource
implements KeyValueResource<Integer, Fortune> {
!
@RestMethod.GET
public Task<Fortune> get(Long key) {
Task<String> retrieveFortuneStr = … ;
!
Task<Fortune> buildFortune =
Tasks.action("getFortune", new Callable<Fortune>() {
@Override public Fortune call() throws Exception {
return new Fortune()
.setMessage(retieveFortuneStr.get());
}
});
return Tasks.seq(retrieveFortuneStr, buildFortune);
}
}
Here we compose together
two tasks together in
sequence using Tasks.seq
The retrieveFortuneStr task is
a non-blocking IO task to get a
fortune string.
The buildFortune task will
create a Fortune from the result
of the retrieveFortuneStr task.
Notice how .get() is used to
access the value of the
completed retrieveFortuneStr.
Async Client
FortuneClient.java
Task<Response<Fortune>> getFortune =
parSeqClient.createTask(new FortunesBuilders.get().id(1L));
!
final Task<Void> printFortune =
Tasks.action("printFortune", new Runnable() {
@Override public void run() {
Response<Fortune> response = getFortune.get();
Fortune fortune = getResponseEntity();
System.out.println(fortune.getMessage());
}
});
!
engine.run(Tasks.seq(getFortune, printFortune));
!
printFortune.await();
Async Client
FortuneClient.java
Task<Response<Fortune>> getFortune =
parSeqClient.createTask(new FortunesBuilders.get().id(1L));
!
final Task<Void> printFortune =
Tasks.action("printFortune", new Runnable() {
@Override public void run() {
Response<Fortune> response = getFortune.get();
Fortune fortune = getResponseEntity();
System.out.println(fortune.getMessage());
}
});
!
engine.run(Tasks.seq(getFortune, printFortune));
!
printFortune.await();
We’ll use ParSeqRestClient,
which can create Tasks from
Rest.li requests.
Async Client
FortuneClient.java
Task<Response<Fortune>> getFortune =
parSeqClient.createTask(new FortunesBuilders.get().id(1L));
!
final Task<Void> printFortune =
Tasks.action("printFortune", new Runnable() {
@Override public void run() {
Response<Fortune> response = getFortune.get();
Fortune fortune = getResponseEntity();
System.out.println(fortune.getMessage());
}
});
!
engine.run(Tasks.seq(getFortune, printFortune));
!
printFortune.await();
Here will compose together
two tasks, also in sequence
using Tasks.seq.
Async Client
FortuneClient.java
Task<Response<Fortune>> getFortune =
parSeqClient.createTask(new FortunesBuilders.get().id(1L));
!
final Task<Void> printFortune =
Tasks.action("printFortune", new Runnable() {
@Override public void run() {
Response<Fortune> response = getFortune.get();
Fortune fortune = getResponseEntity();
System.out.println(fortune.getMessage());
}
});
!
engine.run(Tasks.seq(getFortune, printFortune));
!
printFortune.await();
Here will compose together
two tasks, also in sequence
using Tasks.seq.
The getFortune task will
make a non-blocking request
to our /fortunes resource.
Async Client
FortuneClient.java
Task<Response<Fortune>> getFortune =
parSeqClient.createTask(new FortunesBuilders.get().id(1L));
!
final Task<Void> printFortune =
Tasks.action("printFortune", new Runnable() {
@Override public void run() {
Response<Fortune> response = getFortune.get();
Fortune fortune = getResponseEntity();
System.out.println(fortune.getMessage());
}
});
!
engine.run(Tasks.seq(getFortune, printFortune));
!
printFortune.await();
Here will compose together
two tasks, also in sequence
using Tasks.seq.
The getFortune task will
make a non-blocking request
to our /fortunes resource.
The printFortune task will
print the result of the
getFortune task to stdout.
Async Client
FortuneClient.java
Task<Response<Fortune>> getFortune =
parSeqClient.createTask(new FortunesBuilders.get().id(1L));
!
final Task<Void> printFortune =
Tasks.action("printFortune", new Runnable() {
@Override public void run() {
Response<Fortune> response = getFortune.get();
Fortune fortune = getResponseEntity();
System.out.println(fortune.getMessage());
}
});
!
engine.run(Tasks.seq(getFortune, printFortune));
!
printFortune.await();
We’ll use a ParSeq engine
directly here to execute the
async flow.
Async Client
FortuneClient.java
Task<Response<Fortune>> getFortune =
parSeqClient.createTask(new FortunesBuilders.get().id(1L));
!
final Task<Void> printFortune =
Tasks.action("printFortune", new Runnable() {
@Override public void run() {
Response<Fortune> response = getFortune.get();
Fortune fortune = getResponseEntity();
System.out.println(fortune.getMessage());
}
});
!
engine.run(Tasks.seq(getFortune, printFortune));
!
printFortune.await();
If our client is a command line
application, we need to wait
for our async tasks to
complete before exiting.
Run it again!
Run it again!
“Today’s your lucky day!”
Run it again!
“Today’s your lucky day!”
Much better. Now we can scale.
Next Steps
To learn more, try the
Rest.li Quickstart Tutorial
!
!
For more details on ParSeq,
see the ParSeq Wiki

More Related Content

What's hot

Redux Sagas - React Alicante
Redux Sagas - React AlicanteRedux Sagas - React Alicante
Redux Sagas - React AlicanteIgnacio Martín
 
Functional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayFunctional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayDebasish Ghosh
 
Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Toshiaki Maki
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOPDzmitry Naskou
 
Deciphering Explain Output
Deciphering Explain Output Deciphering Explain Output
Deciphering Explain Output MongoDB
 
Being Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring ReactorBeing Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring ReactorMax Huang
 
Izumi 1.0: Your Next Scala Stack
Izumi 1.0: Your Next Scala StackIzumi 1.0: Your Next Scala Stack
Izumi 1.0: Your Next Scala Stack7mind
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Philip Schwarz
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Domenic Denicola
 
Build Your Own CMS with Apache Sling
Build Your Own CMS with Apache SlingBuild Your Own CMS with Apache Sling
Build Your Own CMS with Apache SlingBob Paulin
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and EffectsMartin Odersky
 
Understanding Reactive Programming
Understanding Reactive ProgrammingUnderstanding Reactive Programming
Understanding Reactive ProgrammingAndres Almiray
 
ASP.NET 開發人員不可不知的 IIS (IIS for ASP.NET Developers)
ASP.NET 開發人員不可不知的 IIS (IIS for ASP.NET Developers)ASP.NET 開發人員不可不知的 IIS (IIS for ASP.NET Developers)
ASP.NET 開發人員不可不知的 IIS (IIS for ASP.NET Developers)Jeff Chu
 
Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門Ryosuke Uchitate
 
RxJS Evolved
RxJS EvolvedRxJS Evolved
RxJS Evolvedtrxcllnt
 
Deep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKDeep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKJosé Paumard
 
Atomicity In Redis: Thomas Hunter
Atomicity In Redis: Thomas HunterAtomicity In Redis: Thomas Hunter
Atomicity In Redis: Thomas HunterRedis Labs
 
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Michel Schudel
 

What's hot (20)

Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
 
Redux Sagas - React Alicante
Redux Sagas - React AlicanteRedux Sagas - React Alicante
Redux Sagas - React Alicante
 
Functional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayFunctional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 Way
 
Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOP
 
React js
React jsReact js
React js
 
Deciphering Explain Output
Deciphering Explain Output Deciphering Explain Output
Deciphering Explain Output
 
Being Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring ReactorBeing Functional on Reactive Streams with Spring Reactor
Being Functional on Reactive Streams with Spring Reactor
 
Izumi 1.0: Your Next Scala Stack
Izumi 1.0: Your Next Scala StackIzumi 1.0: Your Next Scala Stack
Izumi 1.0: Your Next Scala Stack
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
Build Your Own CMS with Apache Sling
Build Your Own CMS with Apache SlingBuild Your Own CMS with Apache Sling
Build Your Own CMS with Apache Sling
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and Effects
 
Understanding Reactive Programming
Understanding Reactive ProgrammingUnderstanding Reactive Programming
Understanding Reactive Programming
 
ASP.NET 開發人員不可不知的 IIS (IIS for ASP.NET Developers)
ASP.NET 開發人員不可不知的 IIS (IIS for ASP.NET Developers)ASP.NET 開發人員不可不知的 IIS (IIS for ASP.NET Developers)
ASP.NET 開發人員不可不知的 IIS (IIS for ASP.NET Developers)
 
Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門
 
RxJS Evolved
RxJS EvolvedRxJS Evolved
RxJS Evolved
 
Deep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKDeep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UK
 
Atomicity In Redis: Thomas Hunter
Atomicity In Redis: Thomas HunterAtomicity In Redis: Thomas Hunter
Atomicity In Redis: Thomas Hunter
 
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
 

Viewers also liked

Scaling LinkedIn - A Brief History
Scaling LinkedIn - A Brief HistoryScaling LinkedIn - A Brief History
Scaling LinkedIn - A Brief HistoryJosh Clemm
 
02 integrate highchart
02 integrate highchart02 integrate highchart
02 integrate highchartErhwen Kuo
 
Clean Code III - Software Craftsmanship at SoCal Code Camp San Diego (07/27/2...
Clean Code III - Software Craftsmanship at SoCal Code Camp San Diego (07/27/2...Clean Code III - Software Craftsmanship at SoCal Code Camp San Diego (07/27/2...
Clean Code III - Software Craftsmanship at SoCal Code Camp San Diego (07/27/2...Theo Jungeblut
 
Building an Online-Recommendation Engine with MongoDB
Building an Online-Recommendation Engine with MongoDBBuilding an Online-Recommendation Engine with MongoDB
Building an Online-Recommendation Engine with MongoDBMongoDB
 
05 integrate redis
05 integrate redis05 integrate redis
05 integrate redisErhwen Kuo
 
Clean Code Part I - Design Patterns at SoCal Code Camp
Clean Code Part I - Design Patterns at SoCal Code CampClean Code Part I - Design Patterns at SoCal Code Camp
Clean Code Part I - Design Patterns at SoCal Code CampTheo Jungeblut
 
The "Big Data" Ecosystem at LinkedIn
The "Big Data" Ecosystem at LinkedInThe "Big Data" Ecosystem at LinkedIn
The "Big Data" Ecosystem at LinkedInSam Shah
 
Accidentally Manager – A Survival Guide for First-Time Engineering Managers
Accidentally Manager – A Survival Guide for First-Time Engineering ManagersAccidentally Manager – A Survival Guide for First-Time Engineering Managers
Accidentally Manager – A Survival Guide for First-Time Engineering ManagersTheo Jungeblut
 
Introduction to Courier
Introduction to CourierIntroduction to Courier
Introduction to CourierJoe Betz
 
Pinot: Realtime Distributed OLAP datastore
Pinot: Realtime Distributed OLAP datastorePinot: Realtime Distributed OLAP datastore
Pinot: Realtime Distributed OLAP datastoreKishore Gopalakrishna
 
Squire: A polyglot application combining Neo4j, MongoDB, Ruby and Scala @ FOS...
Squire: A polyglot application combining Neo4j, MongoDB, Ruby and Scala @ FOS...Squire: A polyglot application combining Neo4j, MongoDB, Ruby and Scala @ FOS...
Squire: A polyglot application combining Neo4j, MongoDB, Ruby and Scala @ FOS...Alberto Perdomo
 
Software Developer and Architecture @ LinkedIn (QCon SF 2014)
Software Developer and Architecture @ LinkedIn (QCon SF 2014)Software Developer and Architecture @ LinkedIn (QCon SF 2014)
Software Developer and Architecture @ LinkedIn (QCon SF 2014)Sid Anand
 
The Play Framework at LinkedIn
The Play Framework at LinkedInThe Play Framework at LinkedIn
The Play Framework at LinkedInYevgeniy Brikman
 
Strata 2013 - LinkedIn Endorsements: Reputation, Virality, and Social Tagging
Strata 2013 - LinkedIn Endorsements: Reputation, Virality, and Social TaggingStrata 2013 - LinkedIn Endorsements: Reputation, Virality, and Social Tagging
Strata 2013 - LinkedIn Endorsements: Reputation, Virality, and Social TaggingSam Shah
 
Play Framework: async I/O with Java and Scala
Play Framework: async I/O with Java and ScalaPlay Framework: async I/O with Java and Scala
Play Framework: async I/O with Java and ScalaYevgeniy Brikman
 
Powerpoint on environmental issues
Powerpoint on environmental issuesPowerpoint on environmental issues
Powerpoint on environmental issuesMonika Uppal
 

Viewers also liked (17)

Scaling LinkedIn - A Brief History
Scaling LinkedIn - A Brief HistoryScaling LinkedIn - A Brief History
Scaling LinkedIn - A Brief History
 
02 integrate highchart
02 integrate highchart02 integrate highchart
02 integrate highchart
 
Clean Code III - Software Craftsmanship at SoCal Code Camp San Diego (07/27/2...
Clean Code III - Software Craftsmanship at SoCal Code Camp San Diego (07/27/2...Clean Code III - Software Craftsmanship at SoCal Code Camp San Diego (07/27/2...
Clean Code III - Software Craftsmanship at SoCal Code Camp San Diego (07/27/2...
 
Building an Online-Recommendation Engine with MongoDB
Building an Online-Recommendation Engine with MongoDBBuilding an Online-Recommendation Engine with MongoDB
Building an Online-Recommendation Engine with MongoDB
 
05 integrate redis
05 integrate redis05 integrate redis
05 integrate redis
 
Clean Code Part I - Design Patterns at SoCal Code Camp
Clean Code Part I - Design Patterns at SoCal Code CampClean Code Part I - Design Patterns at SoCal Code Camp
Clean Code Part I - Design Patterns at SoCal Code Camp
 
The "Big Data" Ecosystem at LinkedIn
The "Big Data" Ecosystem at LinkedInThe "Big Data" Ecosystem at LinkedIn
The "Big Data" Ecosystem at LinkedIn
 
Accidentally Manager – A Survival Guide for First-Time Engineering Managers
Accidentally Manager – A Survival Guide for First-Time Engineering ManagersAccidentally Manager – A Survival Guide for First-Time Engineering Managers
Accidentally Manager – A Survival Guide for First-Time Engineering Managers
 
Introduction to Courier
Introduction to CourierIntroduction to Courier
Introduction to Courier
 
Pinot: Realtime Distributed OLAP datastore
Pinot: Realtime Distributed OLAP datastorePinot: Realtime Distributed OLAP datastore
Pinot: Realtime Distributed OLAP datastore
 
Squire: A polyglot application combining Neo4j, MongoDB, Ruby and Scala @ FOS...
Squire: A polyglot application combining Neo4j, MongoDB, Ruby and Scala @ FOS...Squire: A polyglot application combining Neo4j, MongoDB, Ruby and Scala @ FOS...
Squire: A polyglot application combining Neo4j, MongoDB, Ruby and Scala @ FOS...
 
Software Developer and Architecture @ LinkedIn (QCon SF 2014)
Software Developer and Architecture @ LinkedIn (QCon SF 2014)Software Developer and Architecture @ LinkedIn (QCon SF 2014)
Software Developer and Architecture @ LinkedIn (QCon SF 2014)
 
The Play Framework at LinkedIn
The Play Framework at LinkedInThe Play Framework at LinkedIn
The Play Framework at LinkedIn
 
Strata 2013 - LinkedIn Endorsements: Reputation, Virality, and Social Tagging
Strata 2013 - LinkedIn Endorsements: Reputation, Virality, and Social TaggingStrata 2013 - LinkedIn Endorsements: Reputation, Virality, and Social Tagging
Strata 2013 - LinkedIn Endorsements: Reputation, Virality, and Social Tagging
 
Play Framework: async I/O with Java and Scala
Play Framework: async I/O with Java and ScalaPlay Framework: async I/O with Java and Scala
Play Framework: async I/O with Java and Scala
 
The Programmer
The ProgrammerThe Programmer
The Programmer
 
Powerpoint on environmental issues
Powerpoint on environmental issuesPowerpoint on environmental issues
Powerpoint on environmental issues
 

Similar to Introduction to rest.li

RESTful API In Node Js using Express
RESTful API In Node Js using Express RESTful API In Node Js using Express
RESTful API In Node Js using Express Jeetendra singh
 
Networked APIs with swift
Networked APIs with swiftNetworked APIs with swift
Networked APIs with swiftTim Burks
 
Unit Testing Express Middleware
Unit Testing Express MiddlewareUnit Testing Express Middleware
Unit Testing Express MiddlewareMorris Singer
 
Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Matthew Groves
 
Full Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQLFull Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQLAll Things Open
 
Local data storage for mobile apps
Local data storage for mobile appsLocal data storage for mobile apps
Local data storage for mobile appsIvano Malavolta
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
Writing RESTful web services using Node.js
Writing RESTful web services using Node.jsWriting RESTful web services using Node.js
Writing RESTful web services using Node.jsFDConf
 
Php interview-questions and answers
Php interview-questions and answersPhp interview-questions and answers
Php interview-questions and answerssheibansari
 
540slidesofnodejsbackendhopeitworkforu.pdf
540slidesofnodejsbackendhopeitworkforu.pdf540slidesofnodejsbackendhopeitworkforu.pdf
540slidesofnodejsbackendhopeitworkforu.pdfhamzadamani7
 
GWT Web Socket and data serialization
GWT Web Socket and data serializationGWT Web Socket and data serialization
GWT Web Socket and data serializationGWTcon
 
NodeJS and ExpressJS.pdf
NodeJS and ExpressJS.pdfNodeJS and ExpressJS.pdf
NodeJS and ExpressJS.pdfArthyR3
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasyJBug Italy
 
Spring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. RESTSpring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. RESTSam Brannen
 
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
 

Similar to Introduction to rest.li (20)

RESTful API In Node Js using Express
RESTful API In Node Js using Express RESTful API In Node Js using Express
RESTful API In Node Js using Express
 
RESTing with JAX-RS
RESTing with JAX-RSRESTing with JAX-RS
RESTing with JAX-RS
 
Android and REST
Android and RESTAndroid and REST
Android and REST
 
Networked APIs with swift
Networked APIs with swiftNetworked APIs with swift
Networked APIs with swift
 
Unit Testing Express Middleware
Unit Testing Express MiddlewareUnit Testing Express Middleware
Unit Testing Express Middleware
 
RESTEasy
RESTEasyRESTEasy
RESTEasy
 
Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017
 
Full Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQLFull Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQL
 
Local data storage for mobile apps
Local data storage for mobile appsLocal data storage for mobile apps
Local data storage for mobile apps
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Writing RESTful web services using Node.js
Writing RESTful web services using Node.jsWriting RESTful web services using Node.js
Writing RESTful web services using Node.js
 
Php interview-questions and answers
Php interview-questions and answersPhp interview-questions and answers
Php interview-questions and answers
 
540slidesofnodejsbackendhopeitworkforu.pdf
540slidesofnodejsbackendhopeitworkforu.pdf540slidesofnodejsbackendhopeitworkforu.pdf
540slidesofnodejsbackendhopeitworkforu.pdf
 
GWT Web Socket and data serialization
GWT Web Socket and data serializationGWT Web Socket and data serialization
GWT Web Socket and data serialization
 
NodeJS and ExpressJS.pdf
NodeJS and ExpressJS.pdfNodeJS and ExpressJS.pdf
NodeJS and ExpressJS.pdf
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasy
 
Spring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. RESTSpring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. REST
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Servlets
ServletsServlets
Servlets
 
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...
 

Recently uploaded

call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Pharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyPharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyAnusha Are
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfayushiqss
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedDelhi Call girls
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfkalichargn70th171
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...kalichargn70th171
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 

Recently uploaded (20)

call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Pharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyPharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodology
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 

Introduction to rest.li

  • 2. Let’s implement a Simple REST request
  • 3. Let’s implement a Simple REST request GET /fortunes/1 HTTP/1.1 Accept: application/json Request
  • 4. Let’s implement a Simple REST request GET /fortunes/1 HTTP/1.1 Accept: application/json HTTP/1.1 200 OK Content-Type: application/json Content-Length: … ! { "message": "Today’s your lucky day!" } Request Response
  • 5. Step 1. Write a Data Schema
  • 6. Step 1. Write a Data Schema Fortune.pdsc { "name" : "Fortune", "namespace" : "com.example", "type" : "record", "fields" : [ { "name" : "message", "type" : "string" } ] }
  • 7. Step 1. Write a Data Schema Fortune.pdsc { "name" : "Fortune", "namespace" : "com.example", "type" : "record", "fields" : [ { "name" : "message", "type" : "string" } ] } This schema defines a Fortune record. It has a single message field of type string. Rest.li schemas are based on avro schemas, and supports maps, lists, optional fields, unions and other useful data modeling constructs.
  • 8. Step 1. Write a Data Schema Fortune.pdsc { "name" : "Fortune", "namespace" : "com.example", "type" : "record", "fields" : [ { "name" : "message", "type" : "string" } ] } Rest.li schemas are designed for JSON. Here’s what a Fortune looks like in JSON: { “message”: “Today is your lucky day!” }
  • 9. Step 1. Write a Data Schema Fortune.pdsc { "name" : "Fortune", "namespace" : "com.example", "type" : "record", "fields" : [ { "name" : "message", "type" : "string" } ] } Rest.li’s automatically generates a binding class from our data schema:
  • 10. Step 1. Write a Data Schema Fortune.pdsc { "name" : "Fortune", "namespace" : "com.example", "type" : "record", "fields" : [ { "name" : "message", "type" : "string" } ] } Fortune.java public class Fortune extends RecordTemplate { String getMessage(); void setMessage(String); } Rest.li’s automatically generates a binding class from our data schema: Generated Code
  • 11. Step 1. Write a Data Schema Fortune.pdsc { "name" : "Fortune", "namespace" : "com.example", "type" : "record", "fields" : [ { "name" : "message", "type" : "string" } ] } Fortune.java public class Fortune extends RecordTemplate { String getMessage(); void setMessage(String); } Rest.li’s automatically generates a binding class from our data schema: Generated Code This class is important, we’ll use it in a minute.
  • 12. Step 2. Write a REST Resource
  • 13. FortunesResource.java @RestLiCollection(name = "fortunes") class FortunesResource implements KeyValueResource<Long, Fortune> { ! @RestMethod.GET public Fortune get(Long key) { return new Fortune() .setMessage("Today’s your lucky day!"); } } Step 2. Write a REST Resource
  • 14. FortunesResource.java @RestLiCollection(name = "fortunes") class FortunesResource implements KeyValueResource<Long, Fortune> { ! @RestMethod.GET public Fortune get(Long key) { return new Fortune() .setMessage("Today’s your lucky day!"); } } Step 2. Write a REST Resource Rest.li annotation declares this class as our implementation of the /fortunes resource.
  • 15. FortunesResource.java @RestLiCollection(name = "fortunes") class FortunesResource implements KeyValueResource<Long, Fortune> { ! @RestMethod.GET public Fortune get(Long key) { return new Fortune() .setMessage("Today’s your lucky day!"); } } Step 2. Write a REST Resource Our collection contains Fortune entities, keyed by Long.
  • 16. FortunesResource.java @RestLiCollection(name = "fortunes") class FortunesResource implements KeyValueResource<Long, Fortune> { ! @RestMethod.GET public Fortune get(Long key) { return new Fortune() .setMessage("Today’s your lucky day!"); } } Step 2. Write a REST Resource Our collection contains Fortune entities, keyed by Long. Notice how we use the generated Fortune class here so everything is strongly typed.
  • 17. FortunesResource.java @RestLiCollection(name = "fortunes") class FortunesResource implements KeyValueResource<Long, Fortune> { ! @RestMethod.GET public Fortune get(Long key) { return new Fortune() .setMessage("Today’s your lucky day!"); } } Step 2. Write a REST Resource Here we implement HTTP GET
  • 18. FortunesResource.java @RestLiCollection(name = "fortunes") class FortunesResource implements KeyValueResource<Long, Fortune> { ! @RestMethod.GET public Fortune get(Long key) { return new Fortune() .setMessage("Today’s your lucky day!"); } } Step 2. Write a REST Resource From our resource implementation, Rest.li’s automatically generates an interface definition,
  • 19. FortunesResource.java @RestLiCollection(name = "fortunes") class FortunesResource implements KeyValueResource<Long, Fortune> { ! @RestMethod.GET public Fortune get(Long key) { return new Fortune() .setMessage("Today’s your lucky day!"); } } Step 2. Write a REST Resource fortunes.restspec.json { “path”: “/fortunes”, “supports”: [ “get” ], … } From our resource implementation, Rest.li’s automatically generates an interface definition, Generated Code
  • 20. FortunesResource.java @RestLiCollection(name = "fortunes") class FortunesResource implements KeyValueResource<Long, Fortune> { ! @RestMethod.GET public Fortune get(Long key) { return new Fortune() .setMessage("Today’s your lucky day!"); } } Step 2. Write a REST Resource fortunes.restspec.json { “path”: “/fortunes”, “supports”: [ “get” ], … } From our resource implementation, Rest.li’s automatically generates an interface definition, and client bindings. Generated Code
  • 21. FortunesResource.java @RestLiCollection(name = "fortunes") class FortunesResource implements KeyValueResource<Long, Fortune> { ! @RestMethod.GET public Fortune get(Long key) { return new Fortune() .setMessage("Today’s your lucky day!"); } } Step 2. Write a REST Resource FortunesBuilders.java public class FortunesBuilders { GetRequestBuilder get(); } fortunes.restspec.json { “path”: “/fortunes”, “supports”: [ “get” ], … } From our resource implementation, Rest.li’s automatically generates an interface definition, and client bindings. Generated Code Generated Code
  • 22. FortunesResource.java @RestLiCollection(name = "fortunes") class FortunesResource implements KeyValueResource<Long, Fortune> { ! @RestMethod.GET public Fortune get(Long key) { return new Fortune() .setMessage("Today’s your lucky day!"); } } Step 2. Write a REST Resource FortunesBuilders.java public class FortunesBuilders { GetRequestBuilder get(); } fortunes.restspec.json { “path”: “/fortunes”, “supports”: [ “get” ], … } From our resource implementation, Rest.li’s automatically generates an interface definition, and client bindings. Generated Code Generated Code We’ll use these to build our client.
  • 23. Step 3. Write a Client
  • 24. Step 3. Write a Client ExampleClient.java Response response = restClient.sendRequest(new FortunesBuilders.get().id(1L)).get(); Fortune fortune = response.getEntity(); System.out.println(fortune.getMessage());
  • 25. Step 3. Write a Client ExampleClient.java Response response = restClient.sendRequest(new FortunesBuilders.get().id(1L)).get(); Fortune fortune = response.getEntity(); System.out.println(fortune.getMessage()); We use client bindings generated from our /fortune resource to build an HTTP GET Request.
  • 26. Step 3. Write a Client ExampleClient.java Response response = restClient.sendRequest(new FortunesBuilders.get().id(1L)).get(); Fortune fortune = response.getEntity(); System.out.println(fortune.getMessage()); We use client bindings generated from our /fortune resource to build an HTTP GET Request. And we use the Rest.li RestClient to send the request.
  • 27. Step 3. Write a Client ExampleClient.java Response response = restClient.sendRequest(new FortunesBuilders.get().id(1L)).get(); Fortune fortune = response.getEntity(); System.out.println(fortune.getMessage()); We use client bindings generated from our /fortune resource to build an HTTP GET Request. And we use the Rest.li RestClient to send the request. Notice how everything is strongly typed.
  • 28. Step 3. Write a Client ExampleClient.java Response response = restClient.sendRequest(new FortunesBuilders.get().id(1L)).get(); Fortune fortune = response.getEntity(); System.out.println(fortune.getMessage()); We use client bindings generated from our /fortune resource to build an HTTP GET Request. And we use the Rest.li RestClient to send the request. Notice how everything is strongly typed. But wait, this request is blocking! The .get() forces the thread block and wait for a response from the server. We’ll show how to make this non-blocking shortly.
  • 29. Step 4. Run it!
  • 30. Step 4. Run it! “Today’s your lucky day!”
  • 31. Step 4. Run it! “Today’s your lucky day!” Great! but all our code is synchronous and blocking. What about non-blocking?
  • 32. Importance of async, non-blocking request handling
  • 33. Importance of async, non-blocking request handling Async processing is ideal for making multiple requests to backend systems in parallel and then composing the results of those parallel requests into a single response. For modern internet architectures, where many backend systems are involved in handling each request from a consumer, making calls in parallel to these backend systems dramatically reduces the overall time to response back to the consumer.
  • 34. Importance of async, non-blocking request handling Async processing is ideal for making multiple requests to backend systems in parallel and then composing the results of those parallel requests into a single response. For modern internet architectures, where many backend systems are involved in handling each request from a consumer, making calls in parallel to these backend systems dramatically reduces the overall time to response back to the consumer. Servers running async code scale better because they can handle very large numbers of concurrent requests. This is because, when you write async code, no threads are blocked waiting for something to complete. If you don’t write async code and you need to handle large numbers of concurrent requests, you’ll need one thread per concurrent request. Each thread takes up considerable memory, and when you run out of memory (or max out a thread pool), the server is unable to take on more requests, resulting in timed out requests and in cases of many complex architectures, cascading failure.
  • 36. Async in Rest.li Rest.li integrates with ParSeq for both client and server side async.
  • 37. Async in Rest.li Rest.li integrates with ParSeq for both client and server side async. Using ParSeq, we will write Tasks. Tasks can be composed together in parallel (par) or sequence (seq) into larger tasks. Tasks are executed asynchronously by the ParSeq engine.
  • 38. Async in Rest.li Rest.li integrates with ParSeq for both client and server side async. Using ParSeq, we will write Tasks. Tasks can be composed together in parallel (par) or sequence (seq) into larger tasks. Tasks are executed asynchronously by the ParSeq engine. Let’s modify our Resource Implementation and Client to use ParSeq.
  • 40. Async Resource Implementation FortunesResource.java @RestLiCollection(name = "fortunes") class FortunesResource implements KeyValueResource<Integer, Fortune> { ! @RestMethod.GET public Task<Fortune> get(Long key) { Task<String> retrieveFortuneStr = … ; ! Task<Fortune> buildFortune = Tasks.action("getFortune", new Callable<Fortune>() { @Override public Fortune call() throws Exception { return new Fortune() .setMessage(retieveFortuneStr.get()); } }); return Tasks.seq(retrieveFortuneStr, buildFortune); } }
  • 41. Async Resource Implementation FortunesResource.java @RestLiCollection(name = "fortunes") class FortunesResource implements KeyValueResource<Integer, Fortune> { ! @RestMethod.GET public Task<Fortune> get(Long key) { Task<String> retrieveFortuneStr = … ; ! Task<Fortune> buildFortune = Tasks.action("getFortune", new Callable<Fortune>() { @Override public Fortune call() throws Exception { return new Fortune() .setMessage(retieveFortuneStr.get()); } }); return Tasks.seq(retrieveFortuneStr, buildFortune); } } Rest.li resources methods can return a ParSeq Task. Rest.li will execute them asynchronously and respond with the result when it’s available.
  • 42. Async Resource Implementation FortunesResource.java @RestLiCollection(name = "fortunes") class FortunesResource implements KeyValueResource<Integer, Fortune> { ! @RestMethod.GET public Task<Fortune> get(Long key) { Task<String> retrieveFortuneStr = … ; ! Task<Fortune> buildFortune = Tasks.action("getFortune", new Callable<Fortune>() { @Override public Fortune call() throws Exception { return new Fortune() .setMessage(retieveFortuneStr.get()); } }); return Tasks.seq(retrieveFortuneStr, buildFortune); } } Here we compose together two tasks together in sequence using Tasks.seq
  • 43. Async Resource Implementation FortunesResource.java @RestLiCollection(name = "fortunes") class FortunesResource implements KeyValueResource<Integer, Fortune> { ! @RestMethod.GET public Task<Fortune> get(Long key) { Task<String> retrieveFortuneStr = … ; ! Task<Fortune> buildFortune = Tasks.action("getFortune", new Callable<Fortune>() { @Override public Fortune call() throws Exception { return new Fortune() .setMessage(retieveFortuneStr.get()); } }); return Tasks.seq(retrieveFortuneStr, buildFortune); } } Here we compose together two tasks together in sequence using Tasks.seq The retrieveFortuneStr task is a non-blocking IO task to get a fortune string.
  • 44. Async Resource Implementation FortunesResource.java @RestLiCollection(name = "fortunes") class FortunesResource implements KeyValueResource<Integer, Fortune> { ! @RestMethod.GET public Task<Fortune> get(Long key) { Task<String> retrieveFortuneStr = … ; ! Task<Fortune> buildFortune = Tasks.action("getFortune", new Callable<Fortune>() { @Override public Fortune call() throws Exception { return new Fortune() .setMessage(retieveFortuneStr.get()); } }); return Tasks.seq(retrieveFortuneStr, buildFortune); } } Here we compose together two tasks together in sequence using Tasks.seq The retrieveFortuneStr task is a non-blocking IO task to get a fortune string. The buildFortune task will create a Fortune from the result of the retrieveFortuneStr task. Notice how .get() is used to access the value of the completed retrieveFortuneStr.
  • 45. Async Client FortuneClient.java Task<Response<Fortune>> getFortune = parSeqClient.createTask(new FortunesBuilders.get().id(1L)); ! final Task<Void> printFortune = Tasks.action("printFortune", new Runnable() { @Override public void run() { Response<Fortune> response = getFortune.get(); Fortune fortune = getResponseEntity(); System.out.println(fortune.getMessage()); } }); ! engine.run(Tasks.seq(getFortune, printFortune)); ! printFortune.await();
  • 46. Async Client FortuneClient.java Task<Response<Fortune>> getFortune = parSeqClient.createTask(new FortunesBuilders.get().id(1L)); ! final Task<Void> printFortune = Tasks.action("printFortune", new Runnable() { @Override public void run() { Response<Fortune> response = getFortune.get(); Fortune fortune = getResponseEntity(); System.out.println(fortune.getMessage()); } }); ! engine.run(Tasks.seq(getFortune, printFortune)); ! printFortune.await(); We’ll use ParSeqRestClient, which can create Tasks from Rest.li requests.
  • 47. Async Client FortuneClient.java Task<Response<Fortune>> getFortune = parSeqClient.createTask(new FortunesBuilders.get().id(1L)); ! final Task<Void> printFortune = Tasks.action("printFortune", new Runnable() { @Override public void run() { Response<Fortune> response = getFortune.get(); Fortune fortune = getResponseEntity(); System.out.println(fortune.getMessage()); } }); ! engine.run(Tasks.seq(getFortune, printFortune)); ! printFortune.await(); Here will compose together two tasks, also in sequence using Tasks.seq.
  • 48. Async Client FortuneClient.java Task<Response<Fortune>> getFortune = parSeqClient.createTask(new FortunesBuilders.get().id(1L)); ! final Task<Void> printFortune = Tasks.action("printFortune", new Runnable() { @Override public void run() { Response<Fortune> response = getFortune.get(); Fortune fortune = getResponseEntity(); System.out.println(fortune.getMessage()); } }); ! engine.run(Tasks.seq(getFortune, printFortune)); ! printFortune.await(); Here will compose together two tasks, also in sequence using Tasks.seq. The getFortune task will make a non-blocking request to our /fortunes resource.
  • 49. Async Client FortuneClient.java Task<Response<Fortune>> getFortune = parSeqClient.createTask(new FortunesBuilders.get().id(1L)); ! final Task<Void> printFortune = Tasks.action("printFortune", new Runnable() { @Override public void run() { Response<Fortune> response = getFortune.get(); Fortune fortune = getResponseEntity(); System.out.println(fortune.getMessage()); } }); ! engine.run(Tasks.seq(getFortune, printFortune)); ! printFortune.await(); Here will compose together two tasks, also in sequence using Tasks.seq. The getFortune task will make a non-blocking request to our /fortunes resource. The printFortune task will print the result of the getFortune task to stdout.
  • 50. Async Client FortuneClient.java Task<Response<Fortune>> getFortune = parSeqClient.createTask(new FortunesBuilders.get().id(1L)); ! final Task<Void> printFortune = Tasks.action("printFortune", new Runnable() { @Override public void run() { Response<Fortune> response = getFortune.get(); Fortune fortune = getResponseEntity(); System.out.println(fortune.getMessage()); } }); ! engine.run(Tasks.seq(getFortune, printFortune)); ! printFortune.await(); We’ll use a ParSeq engine directly here to execute the async flow.
  • 51. Async Client FortuneClient.java Task<Response<Fortune>> getFortune = parSeqClient.createTask(new FortunesBuilders.get().id(1L)); ! final Task<Void> printFortune = Tasks.action("printFortune", new Runnable() { @Override public void run() { Response<Fortune> response = getFortune.get(); Fortune fortune = getResponseEntity(); System.out.println(fortune.getMessage()); } }); ! engine.run(Tasks.seq(getFortune, printFortune)); ! printFortune.await(); If our client is a command line application, we need to wait for our async tasks to complete before exiting.
  • 53. Run it again! “Today’s your lucky day!”
  • 54. Run it again! “Today’s your lucky day!” Much better. Now we can scale.
  • 55. Next Steps To learn more, try the Rest.li Quickstart Tutorial ! ! For more details on ParSeq, see the ParSeq Wiki