SlideShare a Scribd company logo
Take a Groovy REST!
by Guillaume Laforge
@glaforge
Take a Groovy REST
Promo Code: ctwjavaone
http://www.manning.com/koenig2/
GROOVY
IN ACTION
2ND EDITION
We know
about
APIs!
http://restlet.com
We know
about
APIs!
http://restlet.com
@glaforge
APISpark — sign-up!
4
http://restlet.com
Take a Groovy REST
Quick intro to REST
ROY FIELDING
RESTDISSERTATION
ROY FIELDING
RESTDISSERTATION
Principled design
of the modern
Web architecture
@glaforge
Representational State Transfer
Architectural properties
• Performance
• Scalability
• Simplicity
• Modifiability
• Visibility
• Portability
• Reliability
Architectural constraints
• Client-server
• Stateless
• Cacheable
• Layered system
• Code on demand (optional)
• Uniform interface
8
@glaforge
REST — Uniform interface
• Identification of resources
• Manipulation of resources 

through representations
• Self-descriptive messages
• HATEOAS 

(Hypermedia As The Engine 

Of Application State)
9
@glaforge
REST — Uniform interface
• Identification of resources
• Manipulation of resources 

through representations
• Self-descriptive messages
• HATEOAS 

(Hypermedia As The Engine 

Of Application State)
9
Resource as URIs
http://api.co/cars/123
@glaforge
REST — Uniform interface
• Identification of resources
• Manipulation of resources 

through representations
• Self-descriptive messages
• HATEOAS 

(Hypermedia As The Engine 

Of Application State)
9
Resource as URIs
http://api.co/cars/123
JSON, XML…
@glaforge
REST — Uniform interface
• Identification of resources
• Manipulation of resources 

through representations
• Self-descriptive messages
• HATEOAS 

(Hypermedia As The Engine 

Of Application State)
9
Resource as URIs
http://api.co/cars/123
JSON, XML…
HTTP GET, POST, PUT, DELETE
media types, cacheability…
@glaforge
REST — Uniform interface
• Identification of resources
• Manipulation of resources 

through representations
• Self-descriptive messages
• HATEOAS 

(Hypermedia As The Engine 

Of Application State)
9
Resource as URIs
http://api.co/cars/123
JSON, XML…
HTTP GET, POST, PUT, DELETE
media types, cacheability…
Hypermedia APIs
HAL, JSON-LD, Siren…
@glaforge
HTTP methods / URIs for collection/item
10
GET
POST
PUT
DELETE
http://api.co/v2/cars/ http://api.co/v2/cars/1234
List all the cars Retrieve an individual car
Create a new car
Replace the entire collection
with a whole new list of cars
Replace or create
an individual car
Delete all the cars Delete an individual car
@glaforge
Common HTTP Status Codes — 1xx
11
@glaforge
Common HTTP Status Codes — 2xx
12
@glaforge
Common HTTP Status Codes — 2xx
12
@glaforge
Common HTTP Status Codes — 2xx
12
@glaforge
Common HTTP Status Codes — 2xx
12
@glaforge
Common HTTP Status Codes — 2xx
12
@glaforge
Common HTTP Status Codes — 2xx
12
@glaforge
Common HTTP Status Codes — 3xx
13
@glaforge
Common HTTP Status Codes — 3xx
13
@glaforge
Common HTTP Status Codes — 3xx
13
@glaforge
Common HTTP Status Codes — 3xx
13
@glaforge
Common HTTP Status Codes — 3xx
13
@glaforge
Common HTTP Status Codes — 3xx
13
@glaforge
Common HTTP Status Codes — 4xx
14
@glaforge
Common HTTP Status Codes — 4xx
14
@glaforge
Common HTTP Status Codes — 4xx
14
@glaforge
Common HTTP Status Codes — 4xx
14
@glaforge
Common HTTP Status Codes — 4xx
14
@glaforge
Common HTTP Status Codes — 4xx
14
@glaforge
Common HTTP Status Codes — 5xx
15
@glaforge
Common HTTP Status Codes — 5xx
15
@glaforge
Common HTTP Status Codes — 5xx
15
@glaforge
Common HTTP Status Codes — 5xx
15
REST — Server-side
@glaforge
Solutions for your REST backend
• Grails
• Ratpack
• Spring Boot
• gServ
• Restlet Framework
• any other 

Web framework!
17
Take a Groovy REST
May the Groovy
force be with you!
@glaforge
gServ
19
def gserv = new GServ()



def bkResource = gserv.resource("/people") {

get ":id", { id ->

def person = personService.get( id )

writeJson person

}



get "/", { ->

def persons = personService.all()

responseHeader "content-type", "application/json"

writeJSON persons

}

}



gserv.http {

static_root '/public/webapp'

get '/faq', file("App.faq.html")



}.start(8080)
@glaforge
Restlet Framework
20
@GrabResolver('http://maven.restlet.com')

@Grab('org.restlet.jse:org.restlet:2.3.2')

import org.restlet.*

import org.restlet.resource.*

import org.restlet.data.*

import org.restlet.routing.*

import static org.restlet.data.MediaType.*



class PeopleResource extends ServerResource {

@Get('json')

String toString() { "{'name': 'Luke Skywalker’}" }

}



new Server(Protocol.HTTP, 8183, PeopleResource).with { server ->

start()

new Router(server.context).attach("/people/{user}", PeopleResource)



assert new ClientResource('http://localhost:8183/people/1')

.get(APPLICATION_JSON).text.contains('Luke Skywalker')



stop()

}
@glaforge
Restlet Framework
20
@GrabResolver('http://maven.restlet.com')

@Grab('org.restlet.jse:org.restlet:2.3.2')

import org.restlet.*

import org.restlet.resource.*

import org.restlet.data.*

import org.restlet.routing.*

import static org.restlet.data.MediaType.*



class PeopleResource extends ServerResource {

@Get('json')

String toString() { "{'name': 'Luke Skywalker’}" }

}



new Server(Protocol.HTTP, 8183, PeopleResource).with { server ->

start()

new Router(server.context).attach("/people/{user}", PeopleResource)



assert new ClientResource('http://localhost:8183/people/1')

.get(APPLICATION_JSON).text.contains('Luke Skywalker')



stop()

}
Starts in
milliseconds
@glaforge
Ratpack
21
@Grab('io.ratpack:ratpack-groovy:0.9.17')

import static ratpack.groovy.Groovy.ratpack

import static groovy.json.JsonOutput.toJson



ratpack {

handlers {

get("/people/:id") {

respond byContent.json {

response.send toJson(

[name: 'Luke Skywalker'])

}

}

}

}
@glaforge
Ratpack
21
@Grab('io.ratpack:ratpack-groovy:0.9.17')

import static ratpack.groovy.Groovy.ratpack

import static groovy.json.JsonOutput.toJson



ratpack {

handlers {

get("/people/:id") {

respond byContent.json {

response.send toJson(

[name: 'Luke Skywalker'])

}

}

}

}
Booh! Ratpack
0.9.17???
@glaforge
Ratpack 1.0 is out!
22
@glaforge
Ratpack
23
@Grab(’org.slf4j:slf4j-simple:1.7.12’)
@Grab(’io.ratpack:ratpack-groovy:1.0.0’)
import static ratpack.groovy.Groovy.ratpack
import static ratpack.groovy.Groovy.htmlBuilder as h
import static ratpack.jackson.Jackson.json as j
ratpack {
handlers {
get { render "foo"}
get("people/:id") {
byContent {
json {
render j(name: "Luke Skywalker")
}
html {
render h {
p "Luke Skywalker"
}
}
@glaforge
Ratpack
24
Take a Groovy REST
Beep, let’s move to
the client side of the
REST force!
REST client-side
REST client-side
@glaforge
REST clients — Web, Java, Android
Web browser

(client-side JavaScript)
• Raw AJAX, jQuery
• Angular’s http request,
Restangular
• Restful.js
+ GrooScript! :-)
Java-based app 

(Android or Java backend)
• Groovy wslite
• Groovy HTTPBuilder
• RetroFit / OkHttp
• Restlet Framework
27
WEB
@glaforge
Restful.js (+ GrooScript ?)
29
JAVA
JAVA& GROOVY
@glaforge
new URL(‘…’).text… or not?
31
'https://starwars.apispark.net/v1/people/1'.toURL().text
@glaforge
new URL(‘…’).text… or not?
31
'https://starwars.apispark.net/v1/people/1'.toURL().text
getText() will do
an HTTP GET
on the URL
403
403The API doesn’t
accept a Java user
agent
@glaforge
Know your GDK!
33
@glaforge
new URL(‘…’).text… take 2!
34
'https://starwars.apispark.net/v1/people/1'

.toURL()

.getText(requestProperties:

['User-Agent': 'Firefox', 

'Accept' : 'application/json'])
@glaforge
new URL(‘…’).text… take 2!
34
'https://starwars.apispark.net/v1/people/1'

.toURL()

.getText(requestProperties:

['User-Agent': 'Firefox', 

'Accept' : 'application/json'])
Let’s ask for
JSON payload
@glaforge
Now JSON-parsed…
35
import groovy.json.*



assert new JsonSlurper().parseText(

'https://starwars.apispark.net/v1/people/1'

.toURL()

.getText(requestProperties:

['User-Agent': 'Firefox', 

'Accept': 'application/json'])

).name == 'Luke Skywalker'
@glaforge
…and spockified!
36
class StarWars extends Specification {

def "retrieve Luke"() {

given: "a URL to the resource"

def url = 'https://starwars.apispark.net/v1'.toURL()



when: "I retrieve and parse the people/1"

def parsed = url.getText(requestProperties:

['User-Agent': 'Firefox', 

'Accept': 'application/json'])



then: "I expect to get Luke"

parsed.contains "Luke Skywalker"

}

}
@glaforge
…and spockified!
36
class StarWars extends Specification {

def "retrieve Luke"() {

given: "a URL to the resource"

def url = 'https://starwars.apispark.net/v1'.toURL()



when: "I retrieve and parse the people/1"

def parsed = url.getText(requestProperties:

['User-Agent': 'Firefox', 

'Accept': 'application/json'])



then: "I expect to get Luke"

parsed.contains "Luke Skywalker"

}

}
Neat for GET,
but not other
methods
supported
@glaforge
…and spockified!
36
class StarWars extends Specification {

def "retrieve Luke"() {

given: "a URL to the resource"

def url = 'https://starwars.apispark.net/v1'.toURL()



when: "I retrieve and parse the people/1"

def parsed = url.getText(requestProperties:

['User-Agent': 'Firefox', 

'Accept': 'application/json'])



then: "I expect to get Luke"

parsed.contains "Luke Skywalker"

}

}
Neat for GET,
but not other
methods
supported
Raw text, no
JSON parsing
@glaforge
Groovy wslite
37
@Grab('com.github.groovy-wslite:groovy-wslite:1.1.0')

import wslite.rest.*

import wslite.http.*



class StarWars3 extends Specification {

static endpoint = 'https://starwars.apispark.net/v1'



def "retrieve Luke"() {

given: "a connection to the API"

def client = new RESTClient(endpoint)



when: "I retrieve the people/1"

def result = client.get(path: '/people/1', headers:

['User-Agent': 'Firefox', 'Accept': 'application/json'])



then: "I expect to get Luke"

result.json.name == "Luke Skywalker"

}

}
@glaforge
Groovy wslite
37
@Grab('com.github.groovy-wslite:groovy-wslite:1.1.0')

import wslite.rest.*

import wslite.http.*



class StarWars3 extends Specification {

static endpoint = 'https://starwars.apispark.net/v1'



def "retrieve Luke"() {

given: "a connection to the API"

def client = new RESTClient(endpoint)



when: "I retrieve the people/1"

def result = client.get(path: '/people/1', headers:

['User-Agent': 'Firefox', 'Accept': 'application/json'])



then: "I expect to get Luke"

result.json.name == "Luke Skywalker"

}

}
Transparent
JSON parsing
@glaforge
Groovy wslite
38


















def client = new RESTClient(endpoint)





def result = client.get(path: '/people/1', headers:

['User-Agent': 'Firefox', 'Accept': 'application/json'])





result.json.name == "Luke Skywalker"



@glaforge
Groovy HTTPBuilder
39
@Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.7.1')

import groovyx.net.http.RESTClient

import static groovyx.net.http.ContentType.JSON



class StarWars4 extends Specification {

static endpoint = 'https://starwars.apispark.net/v1/'



def "retrieve Luke"() {

given: "a connection to the API"

def client = new RESTClient(endpoint)



when: "I retrieve the people/1"

def result = client.get(path: ‘people/1', contentType: JSON,

headers: ['User-Agent': 'Firefox'])



then: "I expect to get Luke"

result.data.name == "Luke Skywalker"

}

}
@glaforge
Groovy HTTPBuilder
40


















def client = new RESTClient(endpoint)





def result = client.get(path: ‘people/1', contentType: JSON,

headers: ['User-Agent': 'Firefox'])





result.data.name == "Luke Skywalker"



@glaforge
Restlet Framework client
41
@GrabResolver('http://maven.restlet.com')

@Grab('org.restlet.jse:org.restlet:2.3.2')

import org.restlet.resource.*

import static org.restlet.data.MediaType.*



class StarWars extends Specification {

static endpoint = 'https://starwars.apispark.net/v1'



def "retrieve Luke"() {

given: "I create a people resource"

def resource = new ClientResource("${endpoint}/people/1")



when: "I retrieve the resource"

def representation = resource.get(APPLICATION_JSON)



then: "I expect that resource to be Luke!"

representation.text.contains "Luke Skywalker"

}

}
@glaforge
Restlet Framework client
41
@GrabResolver('http://maven.restlet.com')

@Grab('org.restlet.jse:org.restlet:2.3.2')

import org.restlet.resource.*

import static org.restlet.data.MediaType.*



class StarWars extends Specification {

static endpoint = 'https://starwars.apispark.net/v1'



def "retrieve Luke"() {

given: "I create a people resource"

def resource = new ClientResource("${endpoint}/people/1")



when: "I retrieve the resource"

def representation = resource.get(APPLICATION_JSON)



then: "I expect that resource to be Luke!"

representation.text.contains "Luke Skywalker"

}

}
Raw text, no
JSON parsing
@glaforge
Restlet Framework client
42




















def resource = new ClientResource("${endpoint}/people/1")





def representation = resource.get(APPLICATION_JSON)





representation.text.contains "Luke Skywalker"



@glaforge
RetroFit
43
@Grab('com.squareup.retrofit:retrofit:1.9.0')

import retrofit.*

import retrofit.http.*



interface StarWarsService {

@Headers(["Accept: application/json",

"User-Agent: Firefox"])

@Get('/people/{id}')

People retrieve(@Path('id') String id)

}



class People { String name }



def restAdapter = new RestAdapter.Builder()

.setEndpoint('https://starwars.apispark.net/v1/')
.build()



def service = restAdapter.create(StarWarsService)

assert service.retrieve('1').name == 'Luke Skywalker'
Miscellaneous
Miscellaneous
@glaforge
DHC by Restlet
45
@glaforge
DHC by Restlet
45
http://bit.ly/dhctuto
@glaforge
httpie
46
@glaforge
REST-assured
47
@Grab('com.jayway.restassured:rest-assured:2.4.1')

import static com.jayway.restassured.RestAssured.*

import static org.hamcrest.Matchers.*



when().

get('https://starwars.apispark.net/v1/people/1').

then().

statusCode(200).

body('name', equalTo('Luke Skywalker')).

body('gender', equalTo('male'))
@glaforge
REST-assured — a Spock approach
48
@Grab('org.spockframework:spock-core:1.0-groovy-2.4')

import spock.lang.*



@Grab('com.jayway.restassured:rest-assured:2.4.1')

import static com.jayway.restassured.RestAssured.*

import static org.hamcrest.Matchers.*



class starwars_rest_assured_spock extends Specification {

def "rest assured and spock"() {

expect:

get('https://starwars.apispark.net/v1/people/1').then().with {

statusCode 200

body 'name', equalTo('Luke Skywalker')

}

}

}
@glaforge
Runscope
49
@glaforge
Mockbin
50
@glaforge
Httpbin
51
@glaforge
Requestb.in
52
Take a Groovy REST
Arg! The Groovy REST
force is too strong!
Thanks for your attention!
Questions & Answers
@glaforge 56
Help us move Groovy forward!
Thanks!
Take a Groovy REST!
@glaforge

More Related Content

PDF
Cassandra Summit 2015 - Building a multi-tenant API PaaS with DataStax Enterp...
PPTX
Integrating Alfresco with Portals
PPTX
Super Size Your Search
PDF
Rest api design by george reese
PDF
Require js training
PPTX
Demystify Salesforce Bulk API
PDF
Your First Scala Web Application using Play 2.1
PDF
Apache ManifoldCF
Cassandra Summit 2015 - Building a multi-tenant API PaaS with DataStax Enterp...
Integrating Alfresco with Portals
Super Size Your Search
Rest api design by george reese
Require js training
Demystify Salesforce Bulk API
Your First Scala Web Application using Play 2.1
Apache ManifoldCF

What's hot (20)

PDF
Code for Startup MVP (Ruby on Rails) Session 1
PDF
Middleware in Golang: InVision's Rye
PPTX
05 integrate redis
PPTX
Rest APIs Training
PDF
GlueCon 2015 - Publish your SQL data as web APIs
PDF
Railsで作るBFFの功罪
PDF
Introduction to GraphQL
PDF
How web works and browser works ? (behind the scenes)
PDF
Mongodb at-gilt-groupe-seattle-2012-09-14-final
PPT
Excellent rest using asp.net web api
PPTX
ASP.NET Web API and HTTP Fundamentals
PPTX
Test in Rest. API testing with the help of Rest Assured.
PDF
SGCE 2015 REST APIs
PPTX
Introduction to Ruby Native Extensions and Foreign Function Interface
PDF
Alfresco WebScript Connector for Apache ManifoldCF
PDF
Lecture #6. automation testing (andrey oleynik)
PDF
GraphQL - A query language to empower your API consumers (NDC Sydney 2017)
PDF
Policy-based Resource Placement Across Hybrid Cloud
PPTX
The ASP.NET Web API for Beginners
PDF
Building Killer RESTful APIs with NodeJs
Code for Startup MVP (Ruby on Rails) Session 1
Middleware in Golang: InVision's Rye
05 integrate redis
Rest APIs Training
GlueCon 2015 - Publish your SQL data as web APIs
Railsで作るBFFの功罪
Introduction to GraphQL
How web works and browser works ? (behind the scenes)
Mongodb at-gilt-groupe-seattle-2012-09-14-final
Excellent rest using asp.net web api
ASP.NET Web API and HTTP Fundamentals
Test in Rest. API testing with the help of Rest Assured.
SGCE 2015 REST APIs
Introduction to Ruby Native Extensions and Foreign Function Interface
Alfresco WebScript Connector for Apache ManifoldCF
Lecture #6. automation testing (andrey oleynik)
GraphQL - A query language to empower your API consumers (NDC Sydney 2017)
Policy-based Resource Placement Across Hybrid Cloud
The ASP.NET Web API for Beginners
Building Killer RESTful APIs with NodeJs

Viewers also liked (9)

PPTX
Workshop - Business Process Management
PDF
Tenha mais tempo e gerencie seus processos com a Bonita
PPTX
Service approach for development Rest API in Symfony2
PDF
Functional Programming with Groovy
PPTX
Apresentação Queimadas
PPT
How Groovy Helps
PPTX
REST & RESTful Web Services
PPTX
Platform as a Service (PaaS)
PDF
SOA na Prática – Criando uma Aplicação BPMN com Bonita Open Solution, Mule ES...
Workshop - Business Process Management
Tenha mais tempo e gerencie seus processos com a Bonita
Service approach for development Rest API in Symfony2
Functional Programming with Groovy
Apresentação Queimadas
How Groovy Helps
REST & RESTful Web Services
Platform as a Service (PaaS)
SOA na Prática – Criando uma Aplicação BPMN com Bonita Open Solution, Mule ES...

Similar to Take a Groovy REST (20)

PDF
FlutterでGraphQLを扱う
PDF
Euroclojure2014: Schema & Swagger - making your Clojure web APIs more awesome
PDF
JHipster Conf 2018 : Connect your JHipster apps to the world of APIs with Ope...
PPTX
Combining Heritrix and PhantomJS for Better Crawling of Pages with Javascript
PDF
Web Services and Android - OSSPAC 2009
PDF
Access Control for HTTP Operations on Linked Data
PPTX
apidays LIVE Australia 2020 - Have your cake and eat it too: GraphQL? REST? W...
PDF
Ratpack Web Framework
PPTX
Construindo aplicações com HTML5, WebSockets, e Java EE 7
PDF
The never-ending REST API design debate -- Devoxx France 2016
PDF
Web Frameworks of the Future
PDF
Apache Solr Changes the Way You Build Sites
PDF
Choisir entre une API RPC, SOAP, REST, GraphQL? 
Et si le problème était ai...
KEY
About Clack
PDF
Arabidopsis Information Portal, Developer Workshop 2014, Introduction
PPTX
Azure and web sites hackaton deck
PDF
Building REST APIs using gRPC and Go
PPTX
Architecture & Workflow of Modern Web Apps
PDF
Into The Box 2018 Ortus Keynote
PPTX
Taking Control of your Data with GraphQL
FlutterでGraphQLを扱う
Euroclojure2014: Schema & Swagger - making your Clojure web APIs more awesome
JHipster Conf 2018 : Connect your JHipster apps to the world of APIs with Ope...
Combining Heritrix and PhantomJS for Better Crawling of Pages with Javascript
Web Services and Android - OSSPAC 2009
Access Control for HTTP Operations on Linked Data
apidays LIVE Australia 2020 - Have your cake and eat it too: GraphQL? REST? W...
Ratpack Web Framework
Construindo aplicações com HTML5, WebSockets, e Java EE 7
The never-ending REST API design debate -- Devoxx France 2016
Web Frameworks of the Future
Apache Solr Changes the Way You Build Sites
Choisir entre une API RPC, SOAP, REST, GraphQL? 
Et si le problème était ai...
About Clack
Arabidopsis Information Portal, Developer Workshop 2014, Introduction
Azure and web sites hackaton deck
Building REST APIs using gRPC and Go
Architecture & Workflow of Modern Web Apps
Into The Box 2018 Ortus Keynote
Taking Control of your Data with GraphQL

More from Restlet (20)

PDF
APIDays - API Design Workshop
PPTX
APIdays 2016 - The State of Web API Languages
PDF
APIStrat Open API Workshop
PDF
DevOps DDay - Streamline DevOps Workflows With APIs
PDF
Restlet Framework NG
PDF
API World 2016 - A five-sided prism polarizing Web API development
PDF
MuleSoft Connect 2016 - Getting started with RAML using Restlet’s visual desi...
PDF
Public and private APIs: differences and challenges
PDF
APIdays 2015 - The State of Web API Languages
PDF
The never-ending REST API design debate
PDF
GlueCon 2015 - How REST APIs can glue all types of devices together
PDF
Transformez vos Google Spreadsheets en API web - DevFest 2014
PPTX
APIdays Paris 2014 - Workshop - Craft and Deploy Your API in a Few Clicks Wit...
PPTX
APIdays Paris 2014 - The State of Web API Languages
PDF
Defrag 2014 - Blend Web IDEs, Open Source and PaaS to Create and Deploy APIs
PDF
QCon SF 2014 - Create and Deploy APIs using Web IDEs, Open Source Frameworks ...
PDF
APIdays Paris - How to Build Your Web API
PDF
Web APIs, the New Language Frontier
PDF
Investir sur son API web (in French)
PDF
Deploy a web API in 15'
APIDays - API Design Workshop
APIdays 2016 - The State of Web API Languages
APIStrat Open API Workshop
DevOps DDay - Streamline DevOps Workflows With APIs
Restlet Framework NG
API World 2016 - A five-sided prism polarizing Web API development
MuleSoft Connect 2016 - Getting started with RAML using Restlet’s visual desi...
Public and private APIs: differences and challenges
APIdays 2015 - The State of Web API Languages
The never-ending REST API design debate
GlueCon 2015 - How REST APIs can glue all types of devices together
Transformez vos Google Spreadsheets en API web - DevFest 2014
APIdays Paris 2014 - Workshop - Craft and Deploy Your API in a Few Clicks Wit...
APIdays Paris 2014 - The State of Web API Languages
Defrag 2014 - Blend Web IDEs, Open Source and PaaS to Create and Deploy APIs
QCon SF 2014 - Create and Deploy APIs using Web IDEs, Open Source Frameworks ...
APIdays Paris - How to Build Your Web API
Web APIs, the New Language Frontier
Investir sur son API web (in French)
Deploy a web API in 15'

Recently uploaded (20)

PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPT
Teaching material agriculture food technology
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Machine learning based COVID-19 study performance prediction
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Advanced IT Governance
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
GamePlan Trading System Review: Professional Trader's Honest Take
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
GDG Cloud Iasi [PUBLIC] Florian Blaga - Unveiling the Evolution of Cybersecur...
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
DOCX
The AUB Centre for AI in Media Proposal.docx
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Per capita expenditure prediction using model stacking based on satellite ima...
Teaching material agriculture food technology
Unlocking AI with Model Context Protocol (MCP)
Dropbox Q2 2025 Financial Results & Investor Presentation
Machine learning based COVID-19 study performance prediction
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Advanced IT Governance
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Spectral efficient network and resource selection model in 5G networks
The Rise and Fall of 3GPP – Time for a Sabbatical?
GamePlan Trading System Review: Professional Trader's Honest Take
NewMind AI Weekly Chronicles - August'25 Week I
Understanding_Digital_Forensics_Presentation.pptx
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Diabetes mellitus diagnosis method based random forest with bat algorithm
GDG Cloud Iasi [PUBLIC] Florian Blaga - Unveiling the Evolution of Cybersecur...
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Mobile App Security Testing_ A Comprehensive Guide.pdf
The AUB Centre for AI in Media Proposal.docx

Take a Groovy REST