Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Funqy HTTP query parameter binding #10968

Merged
merged 1 commit into from
Jul 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/funqy-amazon-lambda-http.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc
////
= Quarkus - Funqy HTTP with Amazon Lambda 
= Quarkus - Funqy HTTP Binding with Amazon Lambda 
:extension-status: preview

include::./attributes.adoc[]
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/funqy-amazon-lambda.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc
////
= Quarkus - Funqy Amazon Lambdas
= Quarkus - Funqy Amazon Lambda Binding
:extension-status: preview

include::./attributes.adoc[]
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/funqy-azure-functions-http.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc
////
= Quarkus - Funqy Azure Functions
= Quarkus - Funqy HTTP Binding with Azure Functions
:extension-status: preview

include::./attributes.adoc[]
Expand Down
221 changes: 207 additions & 14 deletions docs/src/main/asciidoc/funqy-http.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc
////
= Quarkus - Funqy HTTP (Standalone)
= Quarkus - Funqy HTTP Binding (Standalone)

include::./attributes.adoc[]
:extension-status: preview
Expand Down Expand Up @@ -39,6 +39,18 @@ The solution is located in the `funqy-http-quickstart` {quickstarts-tree-url}/fu
If you look at the Java code, you'll see that there is no HTTP specific API. Its just simple Java methods
annotated with `@Funq`. Simple, easy, straightforward.

== Maven Dependencies

To write Funqy HTTP functions, simply include the `quarkus-funqy-http` dependency into your Quarkus `pom.xml` file:

[source, xml]
----
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-funqy-http</artifactId>
</dependency>
----

== Build Project

[source, shell]
Expand All @@ -50,15 +62,13 @@ This starts your functions in Quarkus dev mode.

== Execute Funqy HTTP functions

Funqy HTTP input and output is always JSON. The Jackson JSON parser is used behind the scenes and you can
use Jackson annotations to fine tune your JSON mappings for your input and output objects.

The HTTP POST method can be used to execute any Funqy function. HTTP GET can be used if your function does
not have any input. No other HTTP method can be used besides POST and GET.

The URL path to execute a function is the function name. For example if your function name is `foo` then the URL path
to execute the function would be `/foo`.

The HTTP POST or GET methods can be used to invoke on a function. The return value of the function
is marshalled to JSON using the Jackson JSON library. Jackson annotations can be used. If your function
has an input parameter, a POST invocation must use JSON as the input type. Jackson is also used here for unmarshalling.

You can invoke the `hello` function defined in {quickstarts-tree-url}/funqy-quickstarts/funqy-http-quickstart/src/main/java/org/acme/funqy/PrimitiveFunctions.java[PrimitiveFunctions.java]
by pointing your browser to http://localhost:8080/hello

Expand Down Expand Up @@ -97,15 +107,198 @@ curl "http://localhost:8080/double" \
-d '2'
----

== Maven Dependencies
== GET Query Parameter Mapping

To write Funqy HTTP functions, simply include the `quarkus-funqy-http` dependency into your Quarkus `pom.xml` file:
For GET requests, the Funqy HTTP Binding also has a query parameter mapping for function input parameters.
Only bean style classes and `java.util.Map` can be used for your input parameter. For bean style
classes, query parameter names are mapped to properties on the bean class. Here's an example of a simple
`Map`:

[source, xml]
[source, java]
----
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-funqy-http</artifactId>
</dependency>
@Funq
public String hello(Map<String, Integer> map) {
...
}
----

Key values must be a primitive type (except char) or `String`. Values can be primitives (except char), `String`, `OffsetDateTime` or a complex
bean style class. For the above example, here's the corresponding curl request:

[source, shell]
----
curl "http://localhost:8080/a=1&b=2"
----

The `map` input parameter of the `hello` function would have the key value pairs: `a`->1, `b`->2.

Bean style classes can also be use as the input parameter type. Here's an example:

[source, java]
----
public class Person {
String first;
String last;

public String getFirst() { return first; }
public void setFirst(String first) { this.first = first; }
public String getLast() { return last; }
public void setLast(String last) { this.last = last; }
}

public class MyFunctions {
@Funq
public String greet(Person p) {
return "Hello " + p.getFirst() + " " + p.getLast();
}
}
----

Property values can be any primitive type except `char`. It can also be `String`, and `OffsetDateTime`.
`OffsetDateTime` query param values must be in ISO-8601 format.

You can invoke on this using an HTTP GET and query parameters:

[source, shell]
----
curl "http://localhost:8080/greet?first=Bill&last=Burke"
----

In the above request, the query parameter names are mapped to corresponding properties in the input class.

The input class can also have nested bean classes. Expanding on the previous example:

[source, java]
----
public class Family {
private Person dad;
private Person mom;

public Person getDad() { return dad; }
public void setDad(Person dad) { this.dad = dad; }
public Person getMom() { return mom; }
public void setMom(Person mom) { this.mom = mom; }
}

public class MyFunctions {
@Funq
public String greet(Family family) {
...
}
}

----

In this case, query parameters for nested values use the `.` notation. For example:

[source, shell]
----
curl "http://localhost:8080/greet?dad.first=John&dad.last=Smith&mom.first=Martha&mom.last=Smith"
----

`java.util.List` and `Set` are also supported as property values. For example:

[source, java]
----
public class Family {
...

List<String> pets;
}

public class MyFunctions {
@Funq
public String greet(Family family) {
...
}
}

----

To invoke a GET request, just list the `pets` query parameter multiple times.

[source, shell]
----
curl "http://localhost:8080/greet?pets=itchy&pets=scratchy"
----

For more complex types, `List` and `Set` members must have an identifier in the
query parameter. For example:

[source, java]
----
public class Family {
...

List<Person> kids;
}

public class MyFunctions {
@Funq
public String greet(Family family) {
...
}
}

----

Each `kids` query parameter must identify the kid they are referencing so that
the runtime can figure out which
property values go to which members in the list. Here's the curl request:

[source, shell]
----
curl "http://localhost:8080/greet?kids.1.first=Buffy&kids.2.first=Charlie"
----

The above URL uses the value `1` and `2` to identity the target member of the list, but any unique
string can be used.

A property can also be a `java.util.Map`. The key of the map can be any primitive type and `String`.
For example:

[source, java]
----
public class Family {
...

Map<String, String> address;
}

public class MyFunctions {
@Funq
public String greet(Family family) {
...
}
}
----

The corresponding call would look like this:

[source, shell]
----
curl "http://localhost:8080/greet?address.state=MA&address.city=Boston"
----

If your `Map` value is a complex type, then just continue the notation by adding the property to set at the end.

[source, java]
----
public class Family {
...

Map<String, Address> addresses;
}

public class MyFunctions {
@Funq
public String greet(Family family) {
...
}
}
----

[source, shell]
----
curl "http://localhost:8080/greet?addresses.home.state=MA&addresses.home.city=Boston"
----
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/funqy-knative-events.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc
////
= Quarkus - Funqy Knative Events
= Quarkus - Funqy Knative Events Binding

include::./attributes.adoc[]
:extension-status: preview
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
name: "Funqy AWS Lambda Binding"
metadata:
keywords:
- "funqy"
- "function"
- "lambda"
- "aws"
- "amazon"
guide: "https://quarkus.io/guides/funqy-amazon-lambda"
categories:
- "cloud"
status: "experimental"
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.quarkus.funqy.test;

public class Nested {
private Simple nestedOne;
private Simple nestedTwo;

public Simple getNestedOne() {
return nestedOne;
}

public void setNestedOne(Simple nestedOne) {
this.nestedOne = nestedOne;
}

public Simple getNestedTwo() {
return nestedTwo;
}

public void setNestedTwo(Simple nestedTwo) {
this.nestedTwo = nestedTwo;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package io.quarkus.funqy.test;

import java.util.List;
import java.util.Map;

public class NestedCollection {
private Map<String, Integer> intMap;
private Map<Integer, String> intKeyMap;
private Map<String, Simple> simpleMap;
private List<String> stringList;
private List<Simple> simpleList;

public Map<Integer, String> getIntKeyMap() {
return intKeyMap;
}

public void setIntKeyMap(Map<Integer, String> intKeyMap) {
this.intKeyMap = intKeyMap;
}

public Map<String, Integer> getIntMap() {
return intMap;
}

public void setIntMap(Map<String, Integer> intMap) {
this.intMap = intMap;
}

public Map<String, Simple> getSimpleMap() {
return simpleMap;
}

public void setSimpleMap(Map<String, Simple> simpleMap) {
this.simpleMap = simpleMap;
}

public List<String> getStringList() {
return stringList;
}

public void setStringList(List<String> stringList) {
this.stringList = stringList;
}

public List<Simple> getSimpleList() {
return simpleList;
}

public void setSimpleList(List<Simple> simpleList) {
this.simpleList = simpleList;
}
}
Loading