Giter Club home page Giter Club logo

holon-jaxrs's Introduction

Holon platform JAX-RS module

Latest release: 5.7.0

This is the JAX-RS module of the Holon Platform, which provides support, components and configuration helpers concerning the JAX-RS - Java API for RESTful Web Service standard.

The module main features are:

  • A JAX-RS implementation of the core platform RestClient API, a complete and easy to use RESTful web services Java client, including an asynchronous and a reactive (using Project Reactor) version.
  • A set of standard JAX-RS components to implement server-side API authentication and authorization using platform core APIs and services, such as Realm and AuthContext, in addition to standard javax.annotation.security standard annotations.
  • A complete integration with Swagger OpenAPI Specification, both for version 2 and 3, including support for the PropertyBox core platform data container interface (to be exposed as a Swagger Model definition) and for Swagger API listing endpoints (both in JSON and YAML formats) configuration.
  • Spring Boot auto-configuration classes to automatically register suitable Spring beans (for example beans annotated with @Path or @Provider) as resources in a JAX-RS compliant server.
  • Spring Boot auto-configuration artifact to automatically enable and configure a Resteasy server with Spring integration.
  • A set of Spring Boot starters to setup JAX-RS compliant clients and servers:

See the module documentation for details.

Just like any other platform module, this artifact is part of the Holon Platform ecosystem, but can be also used as a stand-alone library.

See Getting started and the platform documentation for further details.

At-a-glance overview

JAX-RS Property model support:

// Property model
public interface Subject {
		
	static final NumericProperty<Long> ID = NumericProperty.longType("id");
	static final StringProperty NAME = StringProperty.create("name");
	static final StringProperty SURNAME = StringProperty.create("surname");

	static final PropertySet<?> SUBJECT = PropertySet.of(ID, NAME, SURNAME);
		
	static final DataTarget<?> TARGET = DataTarget.named("subjects");

}

// JAX-RS endpoint
@Path("/subjects")
public class SubjectEndpoint {

	@Inject
	private Datastore datastore;
		
	@GET
	@Path("/")
	@Produces(MediaType.APPLICATION_JSON)
	public List<PropertyBox> getSubjects() {
		return datastore.query().target(TARGET).list(SUBJECT);
	}

	@GET
	@Path("/{id}")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getSubject(@PathParam("id") Long id) {
		return datastore.query().target(TARGET).filter(ID.eq(id)).findOne(SUBJECT)
		.map(p -> Response.ok(p).build())
		.orElse(Response.status(Status.NOT_FOUND).build());
	}

	@POST
	@Path("/")
	@Consumes(MediaType.APPLICATION_JSON)
	public Response addSubject(@PropertySetRef(Subject.class) PropertyBox subject) {
		datastore.save(TARGET, subject, DefaultWriteOption.BRING_BACK_GENERATED_IDS);
		return Response.created(URI.create("/api/subjects/" + subject.getValue(ID))).build();
	}

}

JAX-RS API documentation using Swagger:

holon:
  swagger:
    path: 'docs'
    title: 'API title'
    version: 'v1'
@Path("example")
@Component
public class Endpoint {
	/* operations omitted */
}

JAX-RS authentication using JWT and Spring Boot:

holon:
  jwt:
    signature-algorithm: HS256
    sharedkey-base64: eWGZLlCrUjtBZwxgzcLPnA
    expire-hours: 1
    issuer: example-issuer
// Ream with JWT authentication support
@Bean
public Realm realm(JwtConfiguration jwtConfiguration) {
  return Realm.builder().resolver(AuthenticationToken.httpBearerResolver())
  	.authenticator(JwtAuthenticator.builder().configuration(jwtConfiguration).build())
  	.withDefaultAuthorizer().build();
}

// Protected JAX-RS endpoint
@Authenticate
@Path("/api/protected")
public class ApiEndpoint {

	@RolesAllowed("ROLE1")
	@GET
	@Path("/operation")
	public Response userOperation(@Context SecurityContext securityContext) {

		// principal name
		String principalName = securityContext.getUserPrincipal().getName();
		// authentication from JSON Web Token
		Authentication auth = (Authentication) securityContext.getUserPrincipal();

		return Response.ok(principalName).build();
	}

}

JAX-RS RestClient:

RestClient client = RestClient.forTarget("https://host/api");
		
Optional<TestData> data = client.request().path("data/{id}").resolve("id", 1)
	.accept(MediaType.APPLICATION_JSON).getForEntity(TestData.class);

Optional<PropertyBox> value = client.request().path("get_property_box_json")
	.propertySet(SUBJECT).getForEntity(PropertyBox.class);

ResponseEntity<PropertyBox> response = client.request().path("get_property_box_json")
	.propertySet(SUBJECT).get(PropertyBox.class);

List<PropertyBox> values = client.request().path("get_property_boxes_json")
	.propertySet(SUBJECT).getAsList(PropertyBox.class);

ResponseEntity<Void> postResponse = client.request().path("postbox")
	.post(RequestEntity.json(PropertyBox.builder(SUBJECT).set(ID, 1).set(NAME, "Test").build()));

JAX-RS Asynchronous RestClient (since version 5.2):

AsyncRestClient client = AsyncRestClient.forTarget("https://host/api");
		
CompletionStage<Optional<TestData>> data = client.request().path("data/{id}").resolve("id", 1)
	.accept(MediaType.APPLICATION_JSON).getForEntity(TestData.class);

CompletionStage<Optional<PropertyBox>> value = client.request().path("get_property_box_json")
	.propertySet(SUBJECT).getForEntity(PropertyBox.class);

CompletionStage<ResponseEntity<PropertyBox>> response = client.request().path("get_property_box_json")
	.propertySet(SUBJECT).get(PropertyBox.class);

CompletionStage<List<PropertyBox>> values = client.request().path("get_property_boxes_json")
	.propertySet(SUBJECT).getAsList(PropertyBox.class);

CompletionStage<ResponseEntity<Void>> postResponse = client.request().path("postbox")
	.post(RequestEntity.json(PropertyBox.builder(SUBJECT).set(ID, 1).set(NAME, "Test").build()));

JAX-RS Reactive RestClient (since version 5.2):

ReactiveRestClient client = ReactiveRestClient.forTarget("https://host/api");
		
Mono<TestData> data = client.request().path("data/{id}").resolve("id", 1)
	.accept(MediaType.APPLICATION_JSON).getForEntity(TestData.class);

Mono<PropertyBox> value = client.request().path("get_property_box_json")
	.propertySet(SUBJECT).getForEntity(PropertyBox.class);

Mono<ReactiveResponseEntity<PropertyBox>> response = client.request().path("get_property_box_json")
	.propertySet(SUBJECT).get(PropertyBox.class);

Flux<PropertyBox> values = client.request().path("get_property_boxes_json")
	.propertySet(SUBJECT).getAsList(PropertyBox.class);

Mono<ReactiveResponseEntity<Void>> postResponse = client.request().path("postbox")
	.post(RequestEntity.json(PropertyBox.builder(SUBJECT).set(ID, 1).set(NAME, "Test").build()));

See the module documentation for the user guide and a full set of examples.

Code structure

See Holon Platform code structure and conventions to learn about the "real Java API" philosophy with which the project codebase is developed and organized.

Getting started

System requirements

The Holon Platform is built using Java 11, so you need a JRE/JDK version 11 or above to use the platform artifacts.

The JAX-RS specification version 2.0 or above is required.

This module is tested against Jersey version 2.x and Resteasy version 3.x.

Releases

See releases for the available releases. Each release tag provides a link to the closed issues.

Obtain the artifacts

The Holon Platform is open source and licensed under the Apache 2.0 license. All the artifacts (including binaries, sources and javadocs) are available from the Maven Central repository.

The Maven group id for this module is com.holon-platform.jaxrs and a BOM (Bill of Materials) is provided to obtain the module artifacts:

Maven BOM:

<dependencyManagement>
    <dependency>
        <groupId>com.holon-platform.jaxrs</groupId>
        <artifactId>holon-jaxrs-bom</artifactId>
        <version>5.7.0</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
</dependencyManagement>

See the Artifacts list for a list of the available artifacts of this module.

Using the Platform BOM

The Holon Platform provides an overall Maven BOM (Bill of Materials) to easily obtain all the available platform artifacts:

Platform Maven BOM:

<dependencyManagement>
    <dependency>
        <groupId>com.holon-platform</groupId>
        <artifactId>bom</artifactId>
        <version>${platform-version}</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
</dependencyManagement>

See the Artifacts list for a list of the available artifacts of this module.

Build from sources

You can build the sources using Maven (version 3.3.x or above is recommended) like this:

mvn clean install

Getting help

Examples

See the Holon Platform examples repository for a set of example projects.

Contribute

See Contributing to the Holon Platform.

Gitter chat Join the contribute Gitter room for any question and to contact us.

License

All the Holon Platform modules are Open Source software released under the Apache 2.0 license.

Artifacts list

Maven group id: com.holon-platform.jaxrs

Artifact id Description
holon-jaxrs-commons Common JAX-RS support classes
holon-jaxrs-client JAX-RS implementation of the core platform RestClient API
holon-jaxrs-client-reactor Reactive RestClient API JAX-RS implementation using Project Reactor
holon-jaxrs-server JAX-RS server-side authentication and authorization features using platform core APIs and services, such as Realm and AuthContext
holon-jaxrs-swagger-core Core Swagger integration API and annotations
holon-jaxrs-swagger-v2 Swagger specification version 2 integration: JAX-RS API listing endpoints auto-configuration with PropertyBox support
holon-jaxrs-swagger-v3 Swagger/OpenAPI specification version 3 integration: JAX-RS API listing endpoints auto-configuration with PropertyBox support
holon-jaxrs-spring-boot-client JaxrsClientBuilder Spring Boot auto-configuration
holon-jaxrs-spring-boot-jersey Jersey auto-configuration with automatic registration of Spring beans as JAX-RS resources
holon-jaxrs-spring-boot-resteasy Resteasy auto-configuration with Spring integration
holon-starter-jersey Spring Boot JAX-RS server starter using Jersey, Tomcat and Jackson as JSON provider
holon-starter-jersey-gson Spring Boot JAX-RS server starter using Jersey, Tomcat and Gson as JSON provider
holon-starter-jersey-undertow Spring Boot JAX-RS server starter using Jersey, Undertow and Jackson as JSON provider
holon-starter-jersey-undertow-gson Spring Boot JAX-RS server starter using Jersey, Undertow and Gson as JSON provider
holon-starter-jersey-client Spring Boot JAX-RS client starter using Jersey and Jackson as JSON provider
holon-starter-jersey-client-gson Spring Boot JAX-RS client starter using Jersey and Gson as JSON provider
holon-starter-resteasy Spring Boot JAX-RS server starter using Resteasy, Tomcat and Jackson as JSON provider
holon-starter-resteasy-gson Spring Boot JAX-RS server starter using Resteasy, Tomcat and Gson as JSON provider
holon-starter-resteasy-undertow Spring Boot JAX-RS server starter using Resteasy, Undertow and Jackson as JSON provider
holon-starter-resteasy-undertow-gson Spring Boot JAX-RS server starter using Resteasy, Undertow and Gson as JSON provider
holon-starter-resteasy-client Spring Boot JAX-RS client starter using Resteasy and Jackson as JSON provider
holon-starter-resteasy-client-gson Spring Boot JAX-RS client starter using Resteasy and Gson as JSON provider
holon-jaxrs-bom Bill Of Materials
documentation-jaxrs Documentation

holon-jaxrs's People

Contributors

axholo avatar fparoni avatar rrighi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

rrighi

holon-jaxrs's Issues

How to configure an @ApiDefinition annotation for all resource classes in a project?

I'm currently trying out the 5.2.0-alpha1 version with swagger jersey components in my springboot project.
I get the following error when I annotate more than one class with the @Api() swagger annotation:

Validation of the application resource model has failed during application initialization. [[FATAL] A resource model has ambiguous (sub-)resource method for HTTP method GET and input mime-types as defined by"@consumes" and "@produces" annotations at Java methods public javax.ws.rs.core.Response com.holonplatform.jaxrs.swagger.internal.SwaggerApiListingResource.getApiListing(java.lang.String) and public javax.ws.rs.core.Response com.holonplatform.jaxrs.swagger.internal.SwaggerApiListingResource.getApiListing(java.lang.String) at matching regular expression /api-docs/default. These two methods produces and consumes exactly the same mime-types and therefore their invocation as a resource methods will always fail.; source='org.glassfish.jersey.server.model.RuntimeResource@2a7bb45c', [FATAL] A resource model has ambiguous (sub-)resource method for HTTP method GET and input mime-types as defined by"@consumes" and "@produces" annotations at Java methods public javax.ws.rs.core.Response com.holonplatform.jaxrs.swagger.internal.SwaggerApiListingResource.getApiListing(java.lang.String) and public javax.ws.rs.core.Response com.holonplatform.jaxrs.swagger.internal.SwaggerApiListingResource.getApiListing(java.lang.String) at matching regular expression /api-docs. These two methods produces and consumes exactly the same mime-types and therefore their invocation as a resource methods will always fail.; source='org.glassfish.jersey.server.model.RuntimeResource@258b4dfa']

So below is an reduced version of my setup:

@ApiDefinition(docsPath = "/api/docs", title = "...", version = "v1", prettyPrint = true)
@Api(value = "Trolley", consumes = "application/json", produces = "application/json")
@Path("Object")
public class SomeResource {
    @ApiOperation("Just returns a JSON object.")
    @ApiResponses(.....)
    @GET
    @Path("{objectId}")
    public Response getObject(@PathParam("objectId") String templateVar){....}
    
}

@Api(value = "System Test", produces = "text/html")
@Component
@Path("system")
public class TestResource {
    @ApiOperation("Just returns a HTML basic page with information.")
    @ApiResponses(.....)
    @GET
    @Path("check")
    public Response returnSomeHTMLTexT() {....}

}

The other question I have, as it is not clear in the documentation, must I add an @ApiDefinition to all resource classes in order to have them provide JSOn output at the same endpoint uri?

Support for Springboot 2.x and Java 10

Currently it is not possible to create any holon-* based project with springboot 2 (in my case 2.0.3-RELEASE) with a JDK 9/10 target.
I see that there's a 5.2.x (as labelled in the branches) release in the pipeline.
Any chance/news on when to be expecting a compatible release?
Or if there's an interim solution to the RelaxedPropertyResolver issue, I'd be greatful for any information on how to implement it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.