///////////////////////////////////////////////////////////////////////////////

    Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

///////////////////////////////////////////////////////////////////////////////

= JSON Support
:description: Helidon Reactive WebServer JSON support
:keywords: helidon, reactive, reactive streams, reactive java, reactive webserver

== Json Support
The WebServer supports JSON-P. When enabled, you can send and
 receive JSON-P objects transparently.

=== Maven Coordinates

Declare the following dependency in your project:

[source,xml,subs="verbatim,attributes"]
.Webserver JSON-P Dependency
----
<dependency>
    <groupId>io.helidon.media.jsonp</groupId>
    <artifactId>helidon-media-jsonp-server</artifactId>
</dependency>
----

=== Usage

To enable JSON-P support, first register it with the route builder.
Then you can add routes that handle and return JSON.

[source,java]
.Configure JsonSupport and use it for reading and writing of entities
----
Routing.builder()
       .register(JsonSupport.create()) // <1>
       .post("/sayhello", Handler.create(JsonObject.class, this::sayHello)) // <2>
       .build();
----
<1> Register JsonSupport to enable transformation from and to `JsonObject` objects
<2> Register a handler that receives a `JsonObject` as its input.

[source,java]
.Handler that receives and returns JSON objects
----
private static final JsonBuilderFactory jsonFactory = Json.createBuilderFactory(Collections.emptyMap()); <1>

private void sayHello(ServerRequest req, ServerResponse res, JsonObject json) { // <2>
        JsonObject msg = jsonFactory.createObjectBuilder()   // <3>
          .add("message", "Hello " + json.getString("name"))
          .build();
        res.send(msg);                            // <4>
}
----
<1> Using a `JsonBuilderFactory` is more efficient than `Json.createObjectBuilder()`
<2> JsonObject is passed to handler
<3> Create a JsonObject using JSON-P to hold return data
<4> Send JsonObject in response

[source,bash]
.Example of posting JSON to sayHello endpoint
----
curl --noproxy '*' -X POST -H "Content-Type: application/json" \
    http://localhost:8080/sayhello -d '{"name":"Joe"}'
{"message":"Hello Joe"}
----

=== Configuring Json Reader/Writer factories
To configure JSON-P `JsonReaderFactory` and `JsonWriterFactory` that are used by
 the `JsonSupport` instance, create the `JsonSupport` object:

[source,java]
.Create `JsonSupport` with the provided configuration
----
JsonSupport.create(Map.of(JsonGenerator.PRETTY_PRINTING, false))
----
