SlideShare una empresa de Scribd logo
1 de 97
Descargar para leer sin conexión
GraphQL at Yelp

REST in Peace
Tomer Elmalem

tomer@yelp.com

@zehtomer
Yelp’s Mission
Connecting people with great
local businesses.
In the beginning
In the beginning
Enter GraphQL
{
business(id: "yelp") {
name
alias
rating
}
}
{
"data": {
"business": {
"name": "Yelp",
"alias": "yelp-sf",
"rating": 4.9
}
}
}
{
business(id: "yelp") {
name
alias
rating
reviews {
text
}
}
}
{
"data": {
"business": {
"name": "Yelp",
"alias": "yelp-sf",
"rating": 4.9,
"reviews": [{
"text": "some review"
}]
}
}
}
{
business(id: "yelp") {
name
rating
reviews {
text
}
hours {
...
}
}
}
{
"data": {
"business": {
"name": "Yelp",
"rating": 4.9,
"reviews": [{
"text": "some review"
}],
"hours": [{
...
}]
}
}
}
{
b1: business(id: "yelp") {
name
rating
reviews {
text
}
}
b2: business(id: "sforza") {
name
rating
reviews {
text
}
}
}
{
"data": {
"b1": {
"name": "Yelp",
"rating": 4.9,
"reviews": [{
"text": "some review"
}]
},
"b2": {
"name": "Sforza Castle",
"rating": 5.0,
"reviews": [{
"text": "awesome art"
}]
}
}
}
{
business(id: "yelp") {
reviews {
users {
reviews {
business {
categories
}
}
}
}
}
}
{
"data": {
"business": {
"reviews": [{
"users": [{
"reviews": [
{
"business": {
"categories": ["food"]
}
},
{
"business": {
"categories": ["media"]
}
}
]
}]
}]
}
}
}
Let’s start with some vocab
Query
The representation of data you
want returned
query {
business(id: "yelp") {
name
rating
reviews {
text
}
hours {
...
}
}
}
Schema
The representation of your data
structure
class Business(ObjectType):
name = graphene.String()
alias = graphene.String()
reviews = graphene.List(Review)
def resolve_name(root, ...):
return "Yelp"
def resolve_alias(root, ...):
return "yelp-sf"
def resolve_reviews(root, ...):
return [
Review(...)
for review in reviews
]
Fields
The attributes available on your
schema
class Business(ObjectType):
name = graphene.String()
alias = graphene.String()
reviews = graphene.List(Review)
def resolve_name(root, ...):
return "Yelp"
def resolve_alias(root, ...):
return "yelp-sf"
def resolve_reviews(root, ...):
return [
Review(...)
for review in reviews
]
{
"business": {
"name": "Yelp",
"alias": "yelp-sf",
"rating": 4.9
}
}
{
business(id: "yelp") {
name
alias
rating
}
}
Resolvers
Functions that retrieve data for a
specific field in a schema
class Business(ObjectType):
name = graphene.String()
alias = graphene.String()
reviews = graphene.List(Review)
def resolve_name(root, ...):
return "Yelp"
def resolve_alias(root, ...):
return "yelp-sf"
def resolve_reviews(root, ...):
return [
Review(...)
for review in reviews
]
So how does this all work?
Our Setup
• Dedicated public API service

• Python 3.6

• Graphene (Python GraphQL library)

• Pyramid + uWSGI

• Complex 	microservices architecture

• No attached database
Our Setup
• Dedicated public API service

• Python 3.6

• Graphene (Python GraphQL library)

• Pyramid + uWSGI

• Complex 	microservices architecture

• No attached database
{
business(id: "yelp") {
name
reviews {
text
}
}
}
POST /v3/graphql
The View
@view_config(
route_name='api.graphql',
renderer='json',
decorator=verify_api_access,
)
def graphql(request):
schema = graphene.Schema(
query=Query,
)
locale = request.headers.get(
'Accept-Language'
)
context = {
'request': request,
'client': request.client,
'dataloaders': DataLoaders(locale),
}
return schema.execute(
request.body,
context_value=context
)
The View
@view_config(
route_name='api.graphql',
renderer='json',
decorator=verify_api_access,
)
def graphql(request):
schema = graphene.Schema(
query=Query,
)
locale = request.headers.get(
'Accept-Language'
)
context = {
'request': request,
'client': request.client,
'dataloaders': DataLoaders(locale),
}
return schema.execute(
request.body,
context_value=context
)
def verify_api_access(wrapped):
def wrapper(context, request):
access_token = _validate_authorization_header(request)
response = _validate_token(
access_token,
path,
request.client_addr
)
request.client = response
if response.valid:
return wrapped(context, request)
else:
raise UnauthorizedAccessToken()
return wrapper
def verify_api_access(wrapped):
def wrapper(context, request):
access_token = _validate_authorization_header(request)
response = _validate_token(
access_token,
path,
request.client_addr
)
request.client = response
if response.valid:
return wrapped(context, request)
else:
raise UnauthorizedAccessToken()
return wrapper
The View
@view_config(
route_name='api.graphql',
renderer='json',
decorator=verify_api_access,
)
def graphql(request):
schema = graphene.Schema(
query=Query,
)
locale = request.headers.get(
'Accept-Language'
)
context = {
'request': request,
'client': request.client,
'dataloaders': DataLoaders(locale),
}
return schema.execute(
request.body,
context_value=context
)
The View
@view_config(
route_name='api.graphql',
renderer='json',
decorator=verify_api_access,
)
def graphql(request):
schema = graphene.Schema(
query=Query,
)
locale = request.headers.get(
'Accept-Language'
)
context = {
'request': request,
'client': request.client,
'dataloaders': DataLoaders(locale),
}
return schema.execute(
request.body,
context_value=context
)
class Query(graphene.ObjectType):
business = graphene.Field(
Business,
alias=graphene.String(),
)
search = graphene.Field(
Businesses,
term=graphene.String(),
location=graphene.String(),
# ...
)
# ...
class Query(graphene.ObjectType):
business = graphene.Field(
Business,
alias=graphene.String(),
)
search = graphene.Field(
Businesses,
term=graphene.String(),
location=graphene.String(),
# ...
)
# ...
class Query(graphene.ObjectType):
# ...
@verify_limited_graphql_access('graphql')
def resolve_business(root, args, context, info):
alias = args.get('alias')
internalapi_client = get_internal_api_client()
business = internalapi_client.business.get_business(
business_alias=alias
).result()
return context['dataloaders'].businesses.load(business.id)
class Query(graphene.ObjectType):
# ...
@verify_limited_graphql_access('graphql')
def resolve_business(root, args, context, info):
alias = args.get('alias')
internalapi_client = get_internal_api_client()
business = internalapi_client.business.get_business(
business_alias=alias
).result()
return context['dataloaders'].businesses.load(business.id)
class Query(graphene.ObjectType):
# ...
@verify_limited_graphql_access('graphql')
def resolve_business(root, args, context, info):
alias = args.get('alias')
internalapi_client = get_internal_api_client()
business = internalapi_client.business.get_business(
business_alias=alias
).result()
return context['dataloaders'].businesses.load(business.id)
class Query(graphene.ObjectType):
# ...
@verify_limited_graphql_access('graphql')
def resolve_business(root, args, context, info):
alias = args.get('alias')
internalapi_client = get_internal_api_client()
business = internalapi_client.business.get_business(
business_alias=alias
).result()
return context['dataloaders'].businesses.load(business.id)
The View
@view_config(
route_name='api.graphql',
renderer='json',
decorator=verify_api_access,
)
def graphql(request):
schema = graphene.Schema(
query=Query,
)
locale = request.headers.get(
'Accept-Language'
)
context = {
'request': request,
'client': request.client,
'dataloaders': DataLoaders(locale),
}
return schema.execute(
request.body,
context_value=context
)
The View
@view_config(
route_name='api.graphql',
renderer='json',
decorator=verify_api_access,
)
def graphql(request):
schema = graphene.Schema(
query=Query,
)
locale = request.headers.get(
'Accept-Language'
)
context = {
'request': request,
'client': request.client,
'dataloaders': DataLoaders(locale),
}
return schema.execute(
request.body,
context_value=context
)
The View
@view_config(
route_name='api.graphql',
renderer='json',
decorator=verify_api_access,
)
def graphql(request):
schema = graphene.Schema(
query=Query,
)
locale = request.headers.get(
'Accept-Language'
)
context = {
'request': request,
'client': request.client,
'dataloaders': DataLoaders(locale),
}
return schema.execute(
request.body,
context_value=context
)
class Query(graphene.ObjectType):
# ...
@verify_limited_graphql_access('graphql')
def resolve_business(root, args, context, info):
alias = args.get('alias')
internalapi_client = get_internal_api_client()
business = internalapi_client.business.get_business(
business_alias=alias
).result()
return context['dataloaders'].businesses.load(business.id)
The Schema class Business(graphene.ObjectType):
name = graphene.String()
reviews = graphene.List(Reviews)
def resolve_name(root, context, ...):
return root.name
def resolve_reviews(root, context, ...):
return [
Review(...)
for review in root.reviews
]
Dataloaders…?
The N+1 Problem
The N+1 Problem
The inefficient loading of data by making
individual, sequential queries
cats = load_cats()
cat_hats = [
load_hats_for_cat(cat)
for cat in cats
]
# SELECT * FROM cat WHERE ...
# SELECT * FROM hat WHERE catID = 1
# SELECT * FROM hat WHERE catID = 2
# SELECT * FROM hat WHERE catID = ...
query {
b1: business(id: "yelp") {
name
}
b2: business(id: "moma") {
name
}
b3: business(id: "sushi") {
name
}
b4: business(id: "poke") {
name
}
b5: business(id: "taco") {
name
}
b6: business(id: "pizza") {
name
}
}
GET /internalapi/yelp
GET /internalapi/moma
GET /internalapi/sushi
GET /internalapi/poke
GET /internalapi/taco
GET /internalapi/pizza
query {
b1: business(id: "yelp") {
name
}
b2: business(id: "moma") {
name
}
b3: business(id: "sushi") {
name
}
b4: business(id: "poke") {
name
}
b5: business(id: "taco") {
name
}
b6: business(id: "pizza") {
name
}
}
GET /internalapi/yelp
GET /internalapi/moma
GET /internalapi/sushi
GET /internalapi/poke
GET /internalapi/taco
GET /internalapi/pizza
Dataloaders!
• An abstraction layer to load data in your resolvers

• Handle batching ids and deferring execution until all of your data has been
aggregated
query {
b1: business(id: "yelp") {
name
}
b2: business(id: "moma") {
name
}
b3: business(id: "sushi") {
name
}
b4: business(id: "poke") {
name
}
b5: business(id: "taco") {
name
}
b6: business(id: "pizza") {
name
}
}
GET /internalapi/yelp
GET /internalapi/moma
GET /internalapi/sushi
GET /internalapi/poke
GET /internalapi/taco
GET /internalapi/pizza
query {
b1: business(id: "yelp") {
name
}
b2: business(id: "moma") {
name
}
b3: business(id: "sushi") {
name
}
b4: business(id: "poke") {
name
}
b5: business(id: "taco") {
name
}
b6: business(id: "pizza") {
name
}
}
GET /internalapi/yelp,moma,sushi,poke,
The View
@view_config(
route_name='api.graphql',
renderer='json',
decorator=verify_api_access,
)
def graphql(request):
schema = graphene.Schema(
query=Query,
)
locale = request.headers.get(
'Accept-Language'
)
context = {
'request': request,
'client': request.client,
'dataloaders': DataLoaders(locale),
}
return schema.execute(
request.body,
context_value=context
)
class DataLoaders:
def __init__(self, locale):
self.businesses = BusinessDataLoader(locale)
self.coordinates = CoordinatesDataLoader()
self.hours = HoursDataLoader()
self.photos = PhotosDataLoader()
self.events = EventDataLoader()
self.reviews = ReviewsDataLoader(locale)
self.venues = VenueDataLoader()
Dataloader
class BusinessDataLoader(DataLoader):
def __init__(self, locale, **kwargs):
super().__init__(**kwargs)
self._locale = locale
def batch_load_fn(self, biz_ids):
businesses = get_businesses_info(
biz_ids,
self._locale
).result()
biz_id_map = self._biz_map(
businesses
)
return Promise.resolve([
biz_id_map.get(biz_id)
for biz_id in biz_ids
])
def _biz_map(self, businesses):
return {
biz.id: biz
for biz in businesses
}
Dataloader
class BusinessDataLoader(DataLoader):
def __init__(self, locale, **kwargs):
super().__init__(**kwargs)
self._locale = locale
def batch_load_fn(self, biz_ids):
businesses = get_businesses_info(
biz_ids,
self._locale
).result()
biz_id_map = self._biz_map(
businesses
)
return Promise.resolve([
biz_id_map.get(biz_id)
for biz_id in biz_ids
])
def _biz_map(self, businesses):
return {
biz.id: biz
for biz in businesses
}
class Query(graphene.ObjectType):
# ...
@verify_limited_graphql_access('graphql')
def resolve_business(root, args, context, info):
alias = args.get('alias')
internalapi_client = get_internal_api_client()
business = internalapi_client.business.get_business(
business_alias=alias
).result()
return context['dataloaders'].businesses.load(business.id)
Our Setup
• Dedicated public API service

• Python 3.6

• Graphene (Python GraphQL library)

• Pyramid + uWSGI

• Complex 	microservices architecture

• No attached database
Considerations
• Caching

• Performance

• Complexity

• Rate limiting

• Security

• Error handling
Caching
• Edge caching is hard

• Greater diversity of requests

• Many caching strategies don't fit
query {
business(id: "yelp") {
name
}
}
query {
business(id: "yelp") {
name
rating
}
}
query {
search(term: "burrito", latitude: 30.000, longitude: 30.000) {
...
}
}
query {
search(term: "burrito", latitude: 30.001, longitude: 30.001) {
...
}
}
query {
search(term: "Burrito", latitude: 30.000, longitude: 30.000) {
...
}
}
Service Caching
• Network caching proxy

• Generic caching service

• Can wrap any service, applies to everyone
What about bulk data?
Caching in Bulk
• ID-based caching, setup a key: value cache map

• Parse and cache individual models, don't cache the entire response as-is
cached_endpoints:
user.v2: {
ttl: 3600,
pattern: "(^/user/v2(?:?|?.*&)ids=)((?:d|%2C)+)(&.*$|$)",
bulk_support: true,
id_identifier: 'id'
}
cached_endpoints:
user.v2: {
ttl: 3600,
pattern: "(^/user/v2(?:?|?.*&)ids=)((?:d|%2C)+)(&.*$|$)",
bulk_support: true,
id_identifier: 'id'
}
Request Budgets
Request Budgets
X-Ctx-Request-Budget 1000
sleep(0.470)
X-Ctx-Request-Budget 530
Request Budgets
X-Ctx-Request-Budget 1000
sleep(1.470)
X-Ctx-Request-Budget -530
Complexity
{
business(id: "yelp") {
reviews {
users {
reviews {
business {
categories
}
}
}
}
}
}
{
"data": {
"business": {
"reviews": [{
"users": [{
"reviews": [
{
"business": {
"categories": ["food"]
}
},
{
"business": {
"categories": ["media"]
}
}
]
}]
}]
}
}
}
Rate Limiting
Normally
GET https://api.yelp.com/v3/search
Normally
GET https://api.yelp.com/v3/search
GET https://api.yelp.com/v3/search
GET https://api.yelp.com/v3/search
GET https://api.yelp.com/v3/search
GET https://api.yelp.com/v3/search
GET https://api.yelp.com/v3/search
GET https://api.yelp.com/v3/search
GET https://api.yelp.com/v3/search
GET https://api.yelp.com/v3/search
GET https://api.yelp.com/v3/search
GraphQL
POST https://api.yelp.com/v3/graphql
query {
business(id: "yelp-san-francisco") {
name
}
}
GraphQL
POST https://api.yelp.com/v3/graphql
query {
b1: business(id: "yelp-san-francisco") {
name
}
b2: business(id: "garaje-san-francisco") {
name
}
b3: business(id: "moma-san-francisco") {
name
}
}
GraphQL
POST https://api.yelp.com/v3/graphql
query {
search(term: "burrito", location: "sf") {
business {
name
reviews {
rating
text
}
}
}
}
Node-based
• Count individual nodes returned by

the request sent to the API
POST https://api.yelp.com/v3/graphql
query {
search(term: "burrito", location: "sf") {
business {
name
reviews {
rating
text
}
}
}
}
Node-based
• Count individual nodes returned by

the request sent to the API
POST https://api.yelp.com/v3/graphql
query {
search(term: "burrito", location: "sf") {
business {
name
reviews {
rating
text
}
}
}
}
Node-based
• Count individual nodes returned by

the request sent to the API
POST https://api.yelp.com/v3/graphql
query {
search(term: "burrito", location: "sf") {
business {
name
reviews {
rating
text
}
}
}
}
Node-based
• Count individual nodes returned by

the request sent to the API
POST https://api.yelp.com/v3/graphql
query {
search(term: "burrito", location: "sf") {
business {
name
reviews {
rating
text
}
}
}
}
Field-based
• Count each individual field returned 

by the request sent to the API
POST https://api.yelp.com/v3/graphql
query {
search(term: "burrito", location: "sf") {
business {
name
id
}
}
}
Field-based
• Count each individual field returned 

by the request sent to the API
{
"data": {
"search": {
"business": [
{
"name": "El Farolito",
"id": "el-farolito-san-francisco-2"
},
{
"name": "La Taqueria",
"id": "la-taqueria-san-francisco-2"
},
{
"name": "Taqueria Guadalajara",
"id": "taqueria-guadalajara-san-francisco"
},
{
"name": "Taqueria Cancún",
"id": "taqueria-cancún-san-francisco-5"
},
{
"name": "Little Taqueria",
"id": "little-taqueria-san-francisco"
},
{
"name": "Pancho Villa Taqueria",
"id": "pancho-villa-taqueria-san-francisco"
},
{
"name": "Tacorea",
"id": "tacorea-san-francisco"
},
{
"name": "El Burrito Express - San Francisco",
"id": "el-burrito-express-san-francisco-san-francisco"
},
{
"name": "El Burrito Express",
"id": "el-burrito-express-san-francisco"
},
...
]
}
}
Field-based
• Count each individual field returned 

by the request sent to the API
{
"data": {
"search": {
"business": [
{
"name": "El Farolito",
"id": "el-farolito-san-francisco-2"
},
{
"name": "La Taqueria",
"id": "la-taqueria-san-francisco-2"
},
{
"name": "Taqueria Guadalajara",
"id": "taqueria-guadalajara-san-francisco"
},
{
"name": "Taqueria Cancún",
"id": "taqueria-cancún-san-francisco-5"
},
{
"name": "Little Taqueria",
"id": "little-taqueria-san-francisco"
},
{
"name": "Pancho Villa Taqueria",
"id": "pancho-villa-taqueria-san-francisco"
},
{
"name": "Tacorea",
"id": "tacorea-san-francisco"
},
{
"name": "El Burrito Express - San Francisco",
"id": "el-burrito-express-san-francisco-san-francisco"
},
{
"name": "El Burrito Express",
"id": "el-burrito-express-san-francisco"
},
...
]
}
}
Securing the API
• Bulk endpoints to minimize the number of queries

• Network-level caching

• Daily rate limiting

• Limiting the maximum query size

• Per-resolver level authentication

• Persisted queries
Securing the API
• Bulk endpoints to minimize the number of queries

• Network-level caching

• Daily rate limiting

• Limiting the maximum query size

• Per-resolver level authentication

• Persisted queries
class MaxQuerySizeMiddleware:
MAX_SIZE = 2000
def __init__(self):
resolvers_executed = 0
def resolve(self, next, root, info, **args):
# did we hit the max for this query? nope
if resolvers_executed <= MAX_SIZE:
self.resolvers_executed += 1
return next(root, info, **args)
# we hit the max for this query
return None
Easy* failure handling and retries
• GraphQL requests can partially succeed!
{
business(id: "yelp") {
name
rating
reviews {
text
}
hours {
...
}
}
}
{
"data": {
"business": {
"name": "Yelp",
"rating": 4.9,
"reviews": [{
"text": "some review"
}],
"hours": null,
}
},
"errors": [
{
"description": "could not load hours",
"error_code": "HOURS_FAILED"
}
]
}
HTTP 200
Easy* failure handling and retries
• GraphQL requests can partially succeed!

• But… that makes some other failure cases trickier
{
business(id: "123-fake-street") {
name
rating
reviews {
text
}
hours {
...
}
}
}
{
"data": null,
"errors": [
{
"description": "business not found",
"error_code": "BUSINESS_NOT_FOUND"
}
]
}
HTTP 200
def talk():
return
end
Building UI Consistent Android Apps
Saturday - 11.30 in Room 6 
Nicola Corti
{
questions? {
answers
}
}

Más contenido relacionado

La actualidad más candente

Scala, Akka, and Play: An Introduction on Heroku
Scala, Akka, and Play: An Introduction on HerokuScala, Akka, and Play: An Introduction on Heroku
Scala, Akka, and Play: An Introduction on Heroku
Havoc Pennington
 
OSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at Netflix
OSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at NetflixOSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at Netflix
OSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at Netflix
Manish Pandit
 

La actualidad más candente (20)

Javantura v3 - ES6 – Future Is Now – Nenad Pečanac
Javantura v3 - ES6 – Future Is Now – Nenad PečanacJavantura v3 - ES6 – Future Is Now – Nenad Pečanac
Javantura v3 - ES6 – Future Is Now – Nenad Pečanac
 
Lightbend Lagom: Microservices Just Right
Lightbend Lagom: Microservices Just RightLightbend Lagom: Microservices Just Right
Lightbend Lagom: Microservices Just Right
 
Logging in Scala
Logging in ScalaLogging in Scala
Logging in Scala
 
Scala, Akka, and Play: An Introduction on Heroku
Scala, Akka, and Play: An Introduction on HerokuScala, Akka, and Play: An Introduction on Heroku
Scala, Akka, and Play: An Introduction on Heroku
 
Scal`a`ngular - Scala and Angular
Scal`a`ngular - Scala and AngularScal`a`ngular - Scala and Angular
Scal`a`ngular - Scala and Angular
 
Full Stack Scala
Full Stack ScalaFull Stack Scala
Full Stack Scala
 
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
 
Advanced Production Debugging
Advanced Production DebuggingAdvanced Production Debugging
Advanced Production Debugging
 
Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一
Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一
Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play apps
 
FlutterでGraphQLを扱う
FlutterでGraphQLを扱うFlutterでGraphQLを扱う
FlutterでGraphQLを扱う
 
A Step to programming with Apache Spark
A Step to programming with Apache SparkA Step to programming with Apache Spark
A Step to programming with Apache Spark
 
Java 8 in Anger, Devoxx France
Java 8 in Anger, Devoxx FranceJava 8 in Anger, Devoxx France
Java 8 in Anger, Devoxx France
 
Scala Frameworks for Web Application 2016
Scala Frameworks for Web Application 2016Scala Frameworks for Web Application 2016
Scala Frameworks for Web Application 2016
 
OSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at Netflix
OSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at NetflixOSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at Netflix
OSCON 2014 - API Ecosystem with Scala, Scalatra, and Swagger at Netflix
 
Refactoring to Java 8 (Devoxx UK)
Refactoring to Java 8 (Devoxx UK)Refactoring to Java 8 (Devoxx UK)
Refactoring to Java 8 (Devoxx UK)
 
Scala in a wild enterprise
Scala in a wild enterpriseScala in a wild enterprise
Scala in a wild enterprise
 
Javantura v4 - (Spring)Boot your application on Red Hat middleware stack - Al...
Javantura v4 - (Spring)Boot your application on Red Hat middleware stack - Al...Javantura v4 - (Spring)Boot your application on Red Hat middleware stack - Al...
Javantura v4 - (Spring)Boot your application on Red Hat middleware stack - Al...
 
Drilling the Async Library
Drilling the Async LibraryDrilling the Async Library
Drilling the Async Library
 
Exploring Java Heap Dumps (Oracle Code One 2018)
Exploring Java Heap Dumps (Oracle Code One 2018)Exploring Java Heap Dumps (Oracle Code One 2018)
Exploring Java Heap Dumps (Oracle Code One 2018)
 

Destacado

Destacado (20)

Mobile Library Development - stuck between a pod and a jar file - Zan Markan ...
Mobile Library Development - stuck between a pod and a jar file - Zan Markan ...Mobile Library Development - stuck between a pod and a jar file - Zan Markan ...
Mobile Library Development - stuck between a pod and a jar file - Zan Markan ...
 
Tomas Petricek - The Gamma: Democratizing data science - Codemotion Milan 2017
Tomas Petricek - The Gamma: Democratizing data science - Codemotion Milan 2017Tomas Petricek - The Gamma: Democratizing data science - Codemotion Milan 2017
Tomas Petricek - The Gamma: Democratizing data science - Codemotion Milan 2017
 
Dark patterns and mobile UX design - Emilia Ciardi - Codemotion Amsterdam 2017
Dark patterns and mobile UX design - Emilia Ciardi - Codemotion Amsterdam 2017Dark patterns and mobile UX design - Emilia Ciardi - Codemotion Amsterdam 2017
Dark patterns and mobile UX design - Emilia Ciardi - Codemotion Amsterdam 2017
 
Composable architectures The Lego of IT - Alessandro David
Composable architectures The Lego of IT - Alessandro DavidComposable architectures The Lego of IT - Alessandro David
Composable architectures The Lego of IT - Alessandro David
 
Nicola Corti/Valentina Mazzoni - GDG Italia Meetup - Codemotion Milan 2017
Nicola Corti/Valentina Mazzoni - GDG Italia Meetup - Codemotion Milan 2017Nicola Corti/Valentina Mazzoni - GDG Italia Meetup - Codemotion Milan 2017
Nicola Corti/Valentina Mazzoni - GDG Italia Meetup - Codemotion Milan 2017
 
Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...
Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...
Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...
 
Mobile UX for user engagement and monetization - Emilia Ciardi - Codemotion R...
Mobile UX for user engagement and monetization - Emilia Ciardi - Codemotion R...Mobile UX for user engagement and monetization - Emilia Ciardi - Codemotion R...
Mobile UX for user engagement and monetization - Emilia Ciardi - Codemotion R...
 
Downtime is not an option - day 2 operations - Jörg Schad
Downtime is not an option - day 2 operations -  Jörg SchadDowntime is not an option - day 2 operations -  Jörg Schad
Downtime is not an option - day 2 operations - Jörg Schad
 
Roberto Clapis/Stefano Zanero - Night of the living vulnerabilities: forever-...
Roberto Clapis/Stefano Zanero - Night of the living vulnerabilities: forever-...Roberto Clapis/Stefano Zanero - Night of the living vulnerabilities: forever-...
Roberto Clapis/Stefano Zanero - Night of the living vulnerabilities: forever-...
 
Agnieszka Naplocha - Breaking the norm with creative CSS - Codemotion Milan 2017
Agnieszka Naplocha - Breaking the norm with creative CSS - Codemotion Milan 2017Agnieszka Naplocha - Breaking the norm with creative CSS - Codemotion Milan 2017
Agnieszka Naplocha - Breaking the norm with creative CSS - Codemotion Milan 2017
 
The Most Important Thing - Mike Lee - Codemotion Amsterdam 2017
The Most Important Thing - Mike Lee - Codemotion Amsterdam 2017The Most Important Thing - Mike Lee - Codemotion Amsterdam 2017
The Most Important Thing - Mike Lee - Codemotion Amsterdam 2017
 
From Doctor to Coder: A Whole New World? - Aisha Sie - Codemotion Amsterdam 2017
From Doctor to Coder: A Whole New World? - Aisha Sie - Codemotion Amsterdam 2017From Doctor to Coder: A Whole New World? - Aisha Sie - Codemotion Amsterdam 2017
From Doctor to Coder: A Whole New World? - Aisha Sie - Codemotion Amsterdam 2017
 
Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...
Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...
Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...
 
Alessandro Confetti - Learn how to build decentralized and serverless html5 a...
Alessandro Confetti - Learn how to build decentralized and serverless html5 a...Alessandro Confetti - Learn how to build decentralized and serverless html5 a...
Alessandro Confetti - Learn how to build decentralized and serverless html5 a...
 
Dan Persa, Maximilian Fellner - The recipe for scalable frontends - Codemotio...
Dan Persa, Maximilian Fellner - The recipe for scalable frontends - Codemotio...Dan Persa, Maximilian Fellner - The recipe for scalable frontends - Codemotio...
Dan Persa, Maximilian Fellner - The recipe for scalable frontends - Codemotio...
 
Monicelli - Stefano Sanfilippo - Codemotion Roma 2015
Monicelli - Stefano Sanfilippo - Codemotion Roma 2015Monicelli - Stefano Sanfilippo - Codemotion Roma 2015
Monicelli - Stefano Sanfilippo - Codemotion Roma 2015
 
Andrea Maietta - Il fascino della supercazzola: un breve viaggio nel mondo de...
Andrea Maietta - Il fascino della supercazzola: un breve viaggio nel mondo de...Andrea Maietta - Il fascino della supercazzola: un breve viaggio nel mondo de...
Andrea Maietta - Il fascino della supercazzola: un breve viaggio nel mondo de...
 
Lorna Mitchell - Becoming Polyglot - Codemotion Milan 2017
Lorna Mitchell - Becoming Polyglot - Codemotion Milan 2017Lorna Mitchell - Becoming Polyglot - Codemotion Milan 2017
Lorna Mitchell - Becoming Polyglot - Codemotion Milan 2017
 
Webinar: Mario Cartia - Facciamo il Punto su Presente e Futuro dei framework ...
Webinar: Mario Cartia - Facciamo il Punto su Presente e Futuro dei framework ...Webinar: Mario Cartia - Facciamo il Punto su Presente e Futuro dei framework ...
Webinar: Mario Cartia - Facciamo il Punto su Presente e Futuro dei framework ...
 
Fabrizio Cornelli - Antropologia di un Dev(Sec)Ops secondo il modello Hunter ...
Fabrizio Cornelli - Antropologia di un Dev(Sec)Ops secondo il modello Hunter ...Fabrizio Cornelli - Antropologia di un Dev(Sec)Ops secondo il modello Hunter ...
Fabrizio Cornelli - Antropologia di un Dev(Sec)Ops secondo il modello Hunter ...
 

Similar a Tomer Elmalem - GraphQL APIs: REST in Peace - Codemotion Milan 2017

Similar a Tomer Elmalem - GraphQL APIs: REST in Peace - Codemotion Milan 2017 (20)

Performant APIs with GraphQL and PHP (Dutch PHP 2019)
Performant APIs with GraphQL and PHP (Dutch PHP 2019)Performant APIs with GraphQL and PHP (Dutch PHP 2019)
Performant APIs with GraphQL and PHP (Dutch PHP 2019)
 
Data models in Angular 1 & 2
Data models in Angular 1 & 2Data models in Angular 1 & 2
Data models in Angular 1 & 2
 
Overview of GraphQL & Clients
Overview of GraphQL & ClientsOverview of GraphQL & Clients
Overview of GraphQL & Clients
 
Building a GraphQL API in PHP
Building a GraphQL API in PHPBuilding a GraphQL API in PHP
Building a GraphQL API in PHP
 
GraphQL Los Angeles Meetup Slides
GraphQL Los Angeles Meetup SlidesGraphQL Los Angeles Meetup Slides
GraphQL Los Angeles Meetup Slides
 
Crafting [Better] API Clients
Crafting [Better] API ClientsCrafting [Better] API Clients
Crafting [Better] API Clients
 
GraphQL & Prisma from Scratch
GraphQL & Prisma from ScratchGraphQL & Prisma from Scratch
GraphQL & Prisma from Scratch
 
MongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and Typescript
MongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and TypescriptMongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and Typescript
MongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and Typescript
 
Graphql, REST and Apollo
Graphql, REST and ApolloGraphql, REST and Apollo
Graphql, REST and Apollo
 
Flask and Angular: An approach to build robust platforms
Flask and Angular:  An approach to build robust platformsFlask and Angular:  An approach to build robust platforms
Flask and Angular: An approach to build robust platforms
 
Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017
 
Next-generation API Development with GraphQL and Prisma
Next-generation API Development with GraphQL and PrismaNext-generation API Development with GraphQL and Prisma
Next-generation API Development with GraphQL and Prisma
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
 
MongoDB World 2019: Building a GraphQL API with MongoDB, Prisma, & TypeScript
MongoDB World 2019: Building a GraphQL API with MongoDB, Prisma, & TypeScriptMongoDB World 2019: Building a GraphQL API with MongoDB, Prisma, & TypeScript
MongoDB World 2019: Building a GraphQL API with MongoDB, Prisma, & TypeScript
 
Specification-Driven Development of REST APIs by Alexander Zinchuk
Specification-Driven Development of REST APIs by Alexander Zinchuk   Specification-Driven Development of REST APIs by Alexander Zinchuk
Specification-Driven Development of REST APIs by Alexander Zinchuk
 
Scalable web application architecture
Scalable web application architectureScalable web application architecture
Scalable web application architecture
 
Getting Started with GraphQL && PHP
Getting Started with GraphQL && PHPGetting Started with GraphQL && PHP
Getting Started with GraphQL && PHP
 
Drupal Mobile
Drupal MobileDrupal Mobile
Drupal Mobile
 
Managing GraphQL servers with AWS Fargate & Prisma Cloud
Managing GraphQL servers  with AWS Fargate & Prisma CloudManaging GraphQL servers  with AWS Fargate & Prisma Cloud
Managing GraphQL servers with AWS Fargate & Prisma Cloud
 
GraphQL - when REST API is not enough - lessons learned
GraphQL - when REST API is not enough - lessons learnedGraphQL - when REST API is not enough - lessons learned
GraphQL - when REST API is not enough - lessons learned
 

Más de Codemotion

Más de Codemotion (20)

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending story
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storia
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard Altwasser
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
 

Último

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 

Último (20)

Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 

Tomer Elmalem - GraphQL APIs: REST in Peace - Codemotion Milan 2017