Coder Social home page Coder Social logo

katharsis-project / katharsis-framework Goto Github PK

View Code? Open in Web Editor NEW
133.0 133.0 65.0 4.91 MB

Katharsis adds powerful layer for RESTful endpoints providing implementenation of JSON:API standard

Home Page: http://katharsis.io

License: Apache License 2.0

Java 90.90% Shell 0.02% TypeScript 1.27% JavaScript 0.08% HTML 0.31% CSS 7.41%
hateoas java java-library json-api katharsis katharsis-framework katharsis-rs katharsis-servlet katharsis-spring

katharsis-framework's People

Contributors

amaltson avatar broglep-work avatar ccreighton-apptio avatar chabala avatar chb0github avatar choeflake avatar ckarthik17 avatar dmartinpro avatar georgekankava avatar gianinbasler avatar gitter-badger avatar grogdj avatar keithdmoore avatar masterspambot avatar meshuga avatar mitch2na avatar mohlek avatar pcdwr avatar pjweisberg avatar poznachowski avatar ramblurr avatar razmaniandevil avatar reegnz avatar remmeier avatar sandmania avatar waffle-iron avatar weaselmetal avatar woonsan avatar woonsanko avatar yuvalbo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

katharsis-framework's Issues

Response for preflight has invalid HTTP status code 404

From @peavers on June 12, 2016 0:49

Using a very basic Dropwizard + Katharsis setup I'm not sure how to handle preflight requests. This wasn't something I needed to deal with when just using Dropwizard. I've set a very open filter

        FilterRegistration.Dynamic filter = environment.servlets().addFilter("CORS", CrossOriginFilter.class);
        filter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, environment.getApplicationContext().getContextPath() + "*");
        filter.setInitParameter(ALLOWED_METHODS_PARAM, "OPTIONS,GET,PUT,POST,DELETE,HEAD");
        filter.setInitParameter(ALLOWED_ORIGINS_PARAM, "*");
        filter.setInitParameter(ALLOWED_HEADERS_PARAM, "Content-Type,"
            + "X-Requested-With,"
            + "Accept,"
            + "Origin,"
            + "Authorization,"
            + "Access-Control-Request-Method,"
            + "Access-Control-Request-Headers,"
            + "Access-Control-Allow-Origin");
        filter.setInitParameter(ALLOW_CREDENTIALS_PARAM, "true");
        filter.setInitParameter(ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, "*");

But still unable to get a POST request to come through from EmberJs.

I've read through all the documentation but can't find any mention of OPTIONS or what I'm supposed to do in this situation...

Would really appreciate a bit of guidance from someone with more experience;

Copied from original issue: katharsis-project/katharsis-core#339

swagger-katharsis (community growth)

From @ieugen on March 29, 2016 8:24

Hello,

I'm looking for API docuemntation adn I found [1] . It's a bit behind but I think it can be improved and it would be nice to have it as part of the community.

I propose we ask @woonsan if he is willing to maintain swagger-katharsis as part and under katharsis-project, provided of course the other team members agree.

Wdyt @meshuga , @masterspambot ? I'm willing to contribute to the project since I will need to document the API for the project. I'm more inclined to do an offline annotation parsing solution to generate the docs on build for a specific version.

[1] https://github.com/woonsan/swagger-katharsis

Copied from original issue: katharsis-project/katharsis-core#273

Add jsonapi client

From @ieugen on May 18, 2016 11:51

Katharsis implements the server side of things. It would be nice to also have a jsonapi client.

One use case is to write integration tests. I imagine that it would not be a big win (since we might reuse most of the code and if we have implemented something wrong it will work because of code sharing).

Copied from original issue: katharsis-project/katharsis-core#315

Allow spaces in katharsis.config.core.resource.package

From @datagitlies on June 9, 2016 18:36

The katharsis.config.core.resource.package property will not accept a comma separated list of package names if there are spaces before / after the comma(s).

This Works: com.company.service.dto,com.company.service.repository
This Doesn't: com.company.service.dto, com.company.service.repository

It's not a priority for me but it seems like an easy fix that could improve usability for first time users.

Copied from original issue: katharsis-project/katharsis-core#338

Getting Katharsis to adhere to the Json api specification for query parameters

From @dustinstanley on July 27, 2016 2:52

Hi,

I am working on getting katharsis to adhere more strictly to the official specification, especially with regards to the parsing of query parameters. I have reviewed Enhancement #209 which appeared as though it would allow extension of the framework to enable custom parsing of the query parameters, but this appears to be only a partial solution.

I am able to create my own QueryParamsParser and QueryParamsBuilder, but unfortunately KatharsisInvoker depends on the use of the QueryParams object which is not extensible in the same way, and QueryParams contains additional logic for parsing query parameters that I cannot override easily. For example, the setSorting method in QueryParams assumes that the sorting parameter is of the form "sort[resource name][field name]", presumably to allow sorting of different types of resources. However, this diverges from the spec as the examples show that the resource name is not to be specified as a query parameter. http://jsonapi.org/format/#fetching-sorting

Similarly, there is a problem with inclusion of related resources as the spec does not appear to support including the top level resource name as a query parameter, as it is instead assumed by the path in the URL. However, if the resource name is not present as a query parameter, this causes an issue with IncludedRelationshipExtractor as it appears to need the resource name as a query parameter and it is unable to identify the parent resource for which to load the relationships. I could not find a way to grab this from the URL and feed it into the extractor given the current design.

The katharsis parameters approach does appear to be more flexible than the spec which is good but we are concerned about clients using libraries that may strictly adhere to the spec, which could cause issues when calling katharsis services.

Perhaps this is something I am just missing here, but is it possible to make katharsis adhere to the json api specification taking the changes for #209 into account?

Copied from original issue: katharsis-project/katharsis-core#373

Requesting better handling when field and getter have different types

From @pjweisberg on June 2, 2016 21:41

I have a class annotated with @JsonApiResource that contains the following:

    @JsonIgnore
    private Future<Driver> driver;

    @JsonGetter
    @JsonApiToOne
    @JsonApiIncludeByDefault
    @SneakyThrows({ExecutionException.class, InterruptedException.class})
    public Driver getDriver() {
        return fDriver == null ? null : driver.get();
    }

When it gets to the mergeAnnotations method in ResourceInformationBuilder, it merges those into a field whose type is Future. It always uses the type from the field instead of the getter. As a result, it doesn't treat driver as a relationship or generate an entry in the includes array.

Ideally I would like it to use the type information from whichever source has the JsonApi annotations, if present, instead of always using the type information from the field.

Copied from original issue: katharsis-project/katharsis-core#336

Understanding Pagination Implementation

From @Ramblurr on May 24, 2016 17:57

First, thanks @meshuga and @masterspambot for being patient with my support request issues. We're diving heavily into Katharsis fast, and so we have many questions popping up.

As an aside: once we get a basic non-trivial MVP up, I would like to contribute back with a few examples so future people don't need to abuse github issues.


My question tonight is understanding how to implement pagination.

Reading through the code it seems the intention is something like this. The resource we're fetching is Contacts. In this example, we have so many contacts that we require paging of contacts. Also, in this example I am using Spring Data JPA to fetch Contacts. (see spring data jpa paging example here).

So a request comes in GET /api/contact/, things start rolling...

  1. My ContactRepository (extending ResourceRepository), has a findAll() method
final private int DEFAULT_PAGE = 1;
final private int DEFAULT_PAGE_SIZE = 50;

public Contact findAll(QueryParams queryParams) {
   if(queryParams.getPagination().isEmpty()) {
       return contactManager.findAll(new PageRequest(DEFAULT_PAGE, DEFAULT_PAGE_SIZE));
   } else { /* not handled */ }
}
  1. The return value is handled by ResourceRepositoryAdapter.
  2. It passes the return value to ResponseRepository.getResponse()
  3. getResponse() then attempts to fetch the LinksInformation with getLinksInformation()
  4. Assuming I have a class ContactLinksRepository extends LinksRespository, the method LinksInformation getLinksInformation(Iterable<T> resources, QueryParams queryParams); is called on my ContactLinksRepository:
class ContactLinksRepository extends LinksInformation<Contact> {
    LinksInformation getLinksInformation(Iterable<Contact> resources, QueryParams queryParams) {
        /* resources now consists of the collection returned by Spring Data JPA.
           However, all the information about the paging server side has been lost.
           Of course I still have the queryParams, but in this example, the paging
           was enforced by the server.
        */
          // ? <-------------
    }
}

So my questions are, from the perspective of // ? in ContactLinksRepository:

  • How am I supposed to pass the paging information (page = 1, page size = 50) from the ContactRepository to the ContactLinksRepository?
  • To generate the links, I need to know the URL of the resource, how do I know the URL for a Contact?

Copied from original issue: katharsis-project/katharsis-core#328

Namespacing resources

Has anyone tried creating namespaces in Katharsis? We are using the Spring implementation and it looks like if we allowed multiple web prefixes this would work but that would require replacing KatharsisFilterV2. The following is an example of what I am looking for:

Spring property:
katharsis.pathPrefix=/api,/api/vendors

The filter would add both prefixes and in isAcceptablePath (find exact match) and getResurcePath (strips exact match).

Relationships with ids, not entities

From @milanogc on March 31, 2016 13:52

Hi!

I have the following DTO, which has an recursive association:

AccountDTO {
    String id;
    String name;
    String parent; // AccountDTO.id
    List<String> children; // list of AccountDTO.id
}

So, instead of having a list of entities, it has a list of ids. I would like that this relationship to be lazy = false, because all accounts (a tree) are loaded with a single call to "/accounts" (findAll).

Could it be done with Katharsis?

Thank you!

Copied from original issue: katharsis-project/katharsis-core#275

Today's workaround for supporting actions

From @Ramblurr on May 24, 2016 8:42

As per this comment and @meshuga's reply, do we have a way in Katharsis today to workaround the lack of actions support?

Can we handle POSTs to resources with custom json bodies representing actions? Something like

POST /api/employee/:id

{
    action: 'promote',
    title: 'Executive Manager'
}

Do we need to register a custom Jersey resource/endpoint to handle these? If so, how do we return JSON API if we need to return a model?

What is today's solution to this problem (regardless of future JSON API additions)?

Copied from original issue: katharsis-project/katharsis-core#327

Support @JsonView annotations on Repository methods and Object fields/methods

From @cjc343 on March 10, 2016 2:12

When writing JAX-RS endpoints, you can annotate both an endpoint and some object field with @JsonView(SomeClass.class).

Other endpoints/fields may be annotated with a different view, say @JsonView(AnotherClass.class).

This allows different endpoints to deliver different representations of the data. Here's a basic example of what I'd like to be able to do:

@JsonApiResource(type = "tasks")
public class Task {
    public Task() {
        this.id = 1L;
        this.name = "example task with project";
        this.project = new Project(1L);
        this.projectId = project.getId();
    }
    @JsonApiId
    private Long id;
    private String name;

    @JsonApiToOne
    @JsonView(Views.JsonApi.class)
    private Project project;
    @JsonView(Views.LegacyApi.class)
    private Long projectId;
}
public class TaskRepository implements ResourceRepository<Task, Long> {
    @JsonView(Views.JsonApi.class)
    @Override
    public Iterable<Task> findAll(QueryParams requestParams) {
        return Arrays.asList(new Task());
    }

    @JsonView(Views.LegacyApi.class)
    @GET
    @Produces(MediaType.LEGACY)
    @Consumes(MediaType.LEGACY)
    public Collection<Task> legacyFindAll() {
        return Arrays.asList(new Task());
    }
}

This allows the projectId to continue to be delivered via one API (without including the full Project) while Katharsis would ignore the projectId and include only the proper relationship.

Currently, this works as expected for the JAX-RS endpoint, but not for the Katharsis endpoint, which continues to include the projectId as an attribute.

Copied from original issue: katharsis-project/katharsis-core#261

Setting a relationship causes a NullPointerException exception

From @evarga on June 26, 2016 10:25

The version of Katharsis I'm using here is 2.4.1. This issue may be easily reproduced using the Spring Boot Simple Example project (see Katharsis Examples). Here are the steps:

  1. Start the Spring Boot Simple Example program as instructed in the README.md file.
  2. Issue the following curl command from a separate shell:
    curl -v -X PATCH -H "Content-Type: application/vnd.api+json" -H "Accept: application/vnd.api+json" --data '{"data":{"type":"projects","id":"123"}}' http://localhost:8080/api/tasks/1/relationships/project

You will notice the following reported exception in the console, and the returned HTTP status code is 500 Internal Server Error:

io.katharsis.invoker.KatharsisInvokerException: com.fasterxml.jackson.databind.JsonMappingException: [no message for java.lang.NullPointerException]
    at io.katharsis.spring.KatharsisFilterV2.invoke(KatharsisFilterV2.java:104) ~[katharsis-spring-2.4.0.jar:na]
    at io.katharsis.spring.KatharsisFilterV2.doFilter(KatharsisFilterV2.java:81) ~[katharsis-spring-2.4.0.jar:na]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_65]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_65]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.30.jar:8.0.30]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_65]
Caused by: com.fasterxml.jackson.databind.JsonMappingException: [no message for java.lang.NullPointerException]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:141) ~[jackson-databind-2.6.5.jar:2.6.5]
    at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:2383) ~[jackson-databind-2.6.5.jar:2.6.5]
    at com.fasterxml.jackson.core.base.GeneratorBase.writeObject(GeneratorBase.java:324) ~[jackson-core-2.6.5.jar:2.6.5]
    at com.fasterxml.jackson.core.JsonGenerator.writeObjectField(JsonGenerator.java:1415) ~[jackson-core-2.6.5.jar:2.6.5]
    at io.katharsis.jackson.serializer.BaseResponseSerializer.serializeSingle(BaseResponseSerializer.java:91) ~[katharsis-core-2.4.0.jar:na]
    at io.katharsis.jackson.serializer.BaseResponseSerializer.writeResponseWithResources(BaseResponseSerializer.java:77) ~[katharsis-core-2.4.0.jar:na]
    at io.katharsis.jackson.serializer.BaseResponseSerializer.serialize(BaseResponseSerializer.java:44) ~[katharsis-core-2.4.0.jar:na]
    at io.katharsis.jackson.serializer.BaseResponseSerializer.serialize(BaseResponseSerializer.java:22) ~[katharsis-core-2.4.0.jar:na]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:130) ~[jackson-databind-2.6.5.jar:2.6.5]
    at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3559) ~[jackson-databind-2.6.5.jar:2.6.5]
    at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:2893) ~[jackson-databind-2.6.5.jar:2.6.5]
    at io.katharsis.spring.KatharsisFilterV2.dispatchRequest(KatharsisFilterV2.java:158) ~[katharsis-spring-2.4.0.jar:na]
    at io.katharsis.spring.KatharsisFilterV2.invoke(KatharsisFilterV2.java:102) ~[katharsis-spring-2.4.0.jar:na]
    ... 34 common frames omitted
Caused by: java.lang.NullPointerException: null
    at io.katharsis.jackson.serializer.ContainerSerializer.serialize(ContainerSerializer.java:66) ~[katharsis-core-2.4.0.jar:na]
    at io.katharsis.jackson.serializer.ContainerSerializer.serialize(ContainerSerializer.java:42) ~[katharsis-core-2.4.0.jar:na]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:130) ~[jackson-databind-2.6.5.jar:2.6.5]
    ... 46 common frames omitted 

Copied from original issue: katharsis-project/katharsis-core#345

How to remove "relationships" from the leaf object

From @narayar on June 29, 2016 23:13

I have a case where the object is the last resource in the chain. This object doesnt have any relationships further i.e. JsonApiToOne or JsonApiToMany. In this case, the framework is still adding "relationships" object in the API response.

{
    "data": {
        "type": "tasks",
        "id": "1",
        "attributes": {
            "name": "Sample task"
        },
        "relationships": {}
    }
}

As per the JSON API spec - http://jsonapi.org/format/#document-resource-object-relationships if the "relationships" is present, then it has to contain at least one the following: links, data, meta

Copied from original issue: katharsis-project/katharsis-core#350

Support for HEAD & OPTION requests

@ieugen said in issue 326 that...

OPTIONS and HEAD are not supported right now.

I'm wondering if/when HEAD will be supported? I currently get HTTP/1.1 204 No Content for all valid HEAD requests but I'm expecting HTTP/1.1 200 OK. As for OPTIONS... I'm using a CORS Filter thus I don't need katharsis to handle OPTIONS. So, not support needed there.

ResourceRepository save method generic type change

From @chb0github on July 14, 2016 21:16

public interface ResourceRepository<T, ID extends Serializable> {

    <S extends T> S save(S var1);
}

should become:

public interface ResourceRepository<T, ID extends Serializable> {

    <S extends T> S save(T var1);
}

So that you can return an object with extra fields like a timestamp. Refer to the other issue on polymorphism

Copied from original issue: katharsis-project/katharsis-core#362

Includes section of API response stopped showing nested data when include parameters increased

From @srajeev on May 10, 2016 15:57

An API that was working for us stopped including a nested relationship's include in the "Included" section of response after we added 6 new include parameters.

I will use an example similar to our use case to explain the issue:

ManagerResource has a UserResource include. UserResource has an AddressResource. The URL include param was.../manager?include=["user", "user.address"]. This was returning user and address in the included section of the response. But when we added more include params, it stopped returning include relations that are nested one level down. In this case, address stopped showing up in response.

Are there any known limitations or issues with includes of nested objects in Katharsis?

We are on version 0.9.4

Thanks
Shyla

Copied from original issue: katharsis-project/katharsis-core#308

Katharsis to support use of Spring's dispatcherServletFilter

From @bduisenov on June 27, 2016 8:9

Hi. In katharsis spring integration the KatharsisFilter2 is been used to handle requests to jsonapi. Could you tell why Filter has been chosen instead of HandlerMapping & HandlerAdaptor. From my perspective using spring's dispatcherServlet would be more beneficial, as the dispatching process also goes through pre-post processors f.ex.

Copied from original issue: katharsis-project/katharsis-spring#32

Katharsis doesn't honor Spring's @Profile for resources.

From @xbmono on June 2, 2016 7:11

If you mark a class that is marked @JsonApiResource as well as its JsonRepository, if the profile is not active the JsonRepository won't be loaded while Katharsis is loading the resource class and tries to find the appropriate repository and application won't be started up. We need to be able to enable/disable some services based on the Spring's profile.

Example:


@Profile("CallCentre")
@JsonApiResource(type = "infos")
public class Info {
}

@Profile("CallCentre")
@Component
public class InfoJsonRepository implements ResourceRepository<Info, Integer> {
}

Now if profile 'CallCentre' is not active we will get exception during the startup

> Caused by: java.util.NoSuchElementException: null
>                 at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:713) ~[na:1.8.0_60]
>                 at java.util.LinkedHashMap$LinkedValueIterator.next(LinkedHashMap.java:739) ~[na:1.8.0_60]
>                 at com.mycomp.myprod.api.MyProdConfigurer$SpringJsonServiceLocator.getInstance(MyProdConfigurer.java:115) ~[classes/:na]
>                 at io.katharsis.resource.registry.DirectRepositoryEntryBuilder.buildResourceRepository(DirectRepositoryEntryBuilder.java:41) ~[katharsis-core-2.3.0.jar:na]
>                 at io.katharsis.resource.registry.RepositoryEntryBuilderFacade.buildResourceRepository(RepositoryEntryBuilderFacade.java:30) ~[katharsis-core-2.3.0.jar:na]
>                 at io.katharsis.resource.registry.ResourceRegistryBuilder.build(ResourceRegistryBuilder.java:64) ~[katharsis-core-2.3.0.jar:na]
>                 at io.katharsis.resource.registry.ResourceRegistryBuilder.build(ResourceRegistryBuilder.java:41) ~[katharsis-core-2.3.0.jar:na]
>                 at com.mycomp.myprod.api.MyProdConfigurer.resourceRegistry(MyProdConfigurer.java:55) ~[classes/:na]
>                 at com.mycomp.myprod.api.MyProdConfigurer$$EnhancerBySpringCGLIB$$d2ee2f09.CGLIB$resourceRegistry$0(<generated>) ~[classes/:na]
>                 at com.mycomp.myprod.api.MyProdConfigurer$$EnhancerBySpringCGLIB$$d2ee2f09$$FastClassBySpringCGLIB$$3f203db.invoke(<generated>) ~[classes/:na]
>                 at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.2.3.RELEASE.jar:4.2.3.RELEASE]
>                 at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:318) ~[spring-context-4.2.3.RELEASE.jar:4.2.3.RELEASE]
>                 at com.mycomp.myprod.api.MyProdConfigurer$$EnhancerBySpringCGLIB$$d2ee2f09.resourceRegistry(<generated>) ~[classes/:na]
>                 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_60]
>                 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_60]
>                 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_60]
>                 at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_60]
>                 at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
>                 ... 59 common frames omitted

Copied from original issue: katharsis-project/katharsis-spring#30

Use JSON API standard sorting parameters

The current JSON API standard for sorting looks like this:

GET /people?sort=-salary,name

The Katharsis documentation has this to say about sorting:

Katharsis implementation differs form JSON API definition of sorting in order to fit standard query parameter serializing strategy and maximize effective processing of data.

A similar request for Katharsis would be:

GET /people?sort[people][salary]=desc&sort[people][name]=asc

I don't know what 'standard query parameter serializing strategy and maximize effective processing of data' is supposed to mean, but I know that following the standard is the whole point of having a standard. When Katharsis doesn't follow the standard, clients that do follow the standard don't work with Katharsis. So there needs to be a compelling reason to diverge from the standard, or else Katharsis should be made to conform.

There are also issues like #28, which would probably be solved by moving to the standard parameter usage.

Is KatharsisProperties.RESOURCE_DEFAULT_DOMAIN really required?

From @chabala on July 13, 2016 22:53

I see in the example code that specifying RESOURCE_DEFAULT_DOMAIN is recommended.

https://github.com/katharsis-project/katharsis-examples/blob/master/jersey-example/src/main/java/io/katharsis/example/jersey/JerseyApplication.java#L23

In fact, while Katharsis will serve resources without having that property set, all the links that are generated will have null in the place where the URI scheme and hostname were expected.

This seems unnecessary to configure, as JAX-RS will inject a UriInfo object that can be used to obtain that information: https://jersey.java.net/documentation/latest/uris-and-links.html

I expect a call to UriInfo.getBaseUri() would net the same information that is being manually supplied.

I could submit a PR for this, but I thought we might discuss it first.

Copied from original issue: katharsis-project/katharsis-rs#40

Supporting cursor keys and non-Integer Pagination values

From @bradtofel on May 19, 2016 4:7

Currently Katharsis only allows Integer values for pagination. I also note that it is missing 'cursor' from the pagination keys enum, an easy fix.

I see there is a code comment in QueryParams.getPagination() that tells me:

"Katharsis implementation sets on strategy of pagination whereas JSON API definition of pagination is agnostic about pagination strategies."

I'm not sure I understand what that means, but what is the rationale behind locking things down to Integers, and why would Katharsis force a particular pagination strategy on implementations?

My intended use is to provide links to 'first' and 'next' pages within a potentially large collection using a string 'cursor' value:

"links": {
first: "...",
next : "...?page[cursor]=abc123"
},

The string "abc123" will contain information to optimize fetching subsequent pages from my persistence layer. This information cannot be serialized as an Integer.

To do this, it looks like I need to provide a new QueryParamsBuilder, and QueryParams subclass, which has non-standard set/getPagination() methods.

Are there downsides to returning an object from getPagination() that allows fetching values by keys as either Integer or String representation? It seems like it would delay the NumberFormatException to occur in the repository method, but I'm not sure if that's a problem.

Thanks!

Copied from original issue: katharsis-project/katharsis-core#317

Create a java api for JSON API serialization/deserialization

We should create a java api to serialize katharsis resources to JsonApi TopLevel Document and from a Json-api json to a TopLevel Document instance or to a resource directly.

Once we have this API we can use it in the repositories to do stuff like:

  • serialize response to clients
  • parse and validate json api request body
  • the functionality should not depend on Katharsis repositories, only resources
  • the functionality will be similar to jsonapi converter and is quite aproachable
  • we should have integration tests for conversions only
  • it should levereage the additions in #44

If we follow the guidelines people could use just katharsis json-api conversion when they need it and not full katharsis.

PATCH fails for fields that where null before

Assume this payload returned from a GET request

{
  "data": {
    "type": "persons",
    "id": "1",
    "attributes": {
      "name": "Bob",
      "age": null
    }
  }
}

"age":null is only added for explicity, it would not be visible in the returned payload.

Now, if I try to set the age by sending a PATCH request containing

{
  "data": {
    "type": "persons",
    "id": "1",
    "attributes": {
      "age": 18
    }
  }
}

It will not succeed due to a faulty implementation in ResourcePatch.updateValues() which would only update the values that weren't null before. Look out for a PR.

crud-updating-resource-relationships not supported?

From @ern2150 on July 27, 2016 19:46

I have read operations invoking annotated methods in my relationship repositories but I can't get update ops (like @JsonApiSetRelations) to fire when updating the parent resource.
So for the JsonAPI Updating a Resource's Relationships examples, I would expect an ArticleToAuthorRepository @JsonApiSetRelation method to fire, and an ArticleToTags @JsonApiSetRelations method to fire.

Am I way off base? Is this more a JsonAPI 1.1 thing and they mistakenly included it in 1.0 spec?

Copied from original issue: katharsis-project/katharsis-core#374

fields[...] filter propagates down to included objects

From @weaselmetal on July 19, 2016 8:35

A GET to /api/tasks/1?include[tasks]=project&fields[tasks]=name

would also apply the field filter to the included project object. Unless the included object shares field names, the included object would not have any attributes in the json payload.

Copied from original issue: katharsis-project/katharsis-core#367

Katharsis and microservices via Spring Cloud Netflix

From @walternate on May 24, 2016 23:3

Hello,

So I am working on a project using a microservice architecture and Spring Cloud Netflix Zuul, Eureka, etc.

I have managed to get Katharsis working on an individual resource service and works fine when directly addressing the server. The problem arrises when communicating through the gateway proxy, where in this case the links reference the resource server directly and not the proxy.

Digging through the Katharsis code (if I understand it correctly ) it seems that the serviceURL of the resource registry is derived from the location of the resource bound to it when @JsonApiResource is processed, hence why I am getting the resource server URL since thats where that resource is. It seems that Spring Hateoas remedies this through X-Forwarded-host headers from the gateway and adjusts the links to the gateways URL.

So my question's are:

  1. Is Katharsis even possible in a microservice environment where API endpoints are in the resource service and trafficked through a gateway. A remedy for this would be to put API endpoints into the gateway and have Katharsis only run on the gateway and have that collect whats needed from the resource servers. This would result in a monolithic gateway but it's doable I suppose but there would be some duplication of domain objects and relationships.
  2. Would a customized KatharsisFilterv2 be the correct path?
  3. Would some gateway magic be the remedy to tweak the response links before sending out?

At this point the first option seems the fastest and least painful way to go in the near term, but I wanted to ping you Katharsis experts before I start misusing your wonderful library and see if one much wiser than I can lead me on the correct path.

Thanks in advance!

Copied from original issue: katharsis-project/katharsis-spring#29

KatharsisInvokerBuilder and objectMapper

From @weaselmetal on May 19, 2016 14:27

I was trying to do all the required configuration for an objectMapper to be used by katharsis. Registering the JsonModule would be an example. We are using katharsis as a filter (AbstractKatharsisFilter).
Here's the problem: when I pass a preconfigured objectMapper to KatharsisInvokerBuilder.objectMapper(...) then it will not be configured by katharsis to use katharsis' serializers, basically bypassing all of katharsis serialization functionality.
If I don't pass an objectMapper to this builder method, then katharsis will create a new, properly configured objectMapper, but it will be inaccessible to me for further configuration.

For now, I ended up extending KatharsisInvokerBuilder (which basically copies all code of super class) and also configure a passed objectMapper bean (spring managed).
This is an excerpt of the build() method:

@Override
public KatharsisInvoker build() throws Exception
{
    // ... all stuff above

    if (objectMapper == null)
    {
        objectMapper = createObjectMapper(resourceRegistry);

    } else
    {
        // that's the important thing to do!
        objectMapper.registerModule(createDataBindingModule(resourceRegistry));
    }

    // more stuff

    return new KatharsisInvoker(objectMapper, queryParamsBuilder, resourceRegistry,
            requestDispatcher);
}

This allows me to inject a properly configured objectMapper whenever I need do (de)serialize stuff.
Btw, I do miss javadoc direly.

Talking about javadoc, this documentation seems wrong:

/**
 * Set prefix to be searched when performing method matching and building building <i>links</i> objects in responses. The name of the configuration property is <tt>{@value}</tt>.
 */
public static final String WEB_PATH_PREFIX = "katharsis.config.web.path.prefix";

The specified prefix is NOT included in the created links. Link only uses defaultDomain plus resource type for the link. I think the docu should stick and the implementation should do what the javadoc says. Makes sense to me.
Thanks!

Copied from original issue: katharsis-project/katharsis-servlet#24

Unsupported Method requests result in a 500 error instead of a 405

From @robmartin0 on April 20, 2016 10:58

If a method is not supported for an endpoint then ControllerRegistry throws a MethodNotFoundException. This class has default access level meaning it is not possible to write a JsonApiExceptionMapper to do the mapping manually.

Copied from original issue: katharsis-project/katharsis-core#295

Allow metrics collection

From @meshuga on April 21, 2016 20:7

Add metrics functionality for Katharsis. It should be possible to integrate with web framework functionalities e.g. Dropwizard/Jersey metrics (https://dropwizard.github.io/metrics/3.1.0/apidocs/com/codahale/metrics/jersey2/InstrumentedResourceMethodApplicationListener.html) or Spring metrics (https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-metrics.html). It should be possible to gather infomrations about requests and exceptions.
Plus add docs on how to do that.

Copied from original issue: katharsis-project/katharsis-core#299

PropertyUtils.getPropertyValue - Finding "wrong" getter

From @corrspt on July 18, 2016 19:16

Hi Guys,

I'm sorry if this is not really an issue with Katharsis, but I would like to ask if someone has an opinion on why this might happen. I'm using Play Framework (2.5) with Katharsis 2.1.1 and using reflections 0.9.9. As Katharsis does not have a direct integration with play, I sort of have a hack to make it work, but still.

I'm getting an error like the following:

2016-07-18T18:39:14.512107+00:00 app[web.1]:  ... 66 common frames omitted
2016-07-18T18:39:14.512108+00:00 app[web.1]: Caused by: java.lang.reflect.InvocationTargetException: null
2016-07-18T18:39:14.512108+00:00 app[web.1]:  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
2016-07-18T18:39:14.512109+00:00 app[web.1]:  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
2016-07-18T18:39:14.512110+00:00 app[web.1]:  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2016-07-18T18:39:14.512110+00:00 app[web.1]:  at java.lang.reflect.Method.invoke(Method.java:498)
2016-07-18T18:39:14.512111+00:00 app[web.1]:  at io.katharsis.utils.PropertyUtils.getPropertyValue(PropertyUtils.java:79)
2016-07-18T18:39:14.512112+00:00 app[web.1]:  at io.katharsis.utils.PropertyUtils.getProperty(PropertyUtils.java:47)
2016-07-18T18:39:14.512112+00:00 app[web.1]:  ... 72 common frames omitted
2016-07-18T18:39:14.512113+00:00 app[web.1]: Caused by: java.lang.NoSuchMethodError: com.example.models.Certificate.getShieldingCapFluxCommercialDesignationTestPiece()Lcom/google/common/base/Optional;

This error only occurs on my app deployed on Heroku, not on my local machine.
The error is really strange because, it basically says that it does not find the getShieldingCapFluxCommercialDesignationTestPiece method that returns a google Optional, which makes sense because I'm using Java 8' Optional (and nowhere in my class, or even in my project I'm using Google's Optional directly in my code).

Does anyone know why this might happen? I tried removing the usage of "Optional" in my code and deployed it to Heroku and it seems to be working. On the other hand, I have other classes which use Optional (java.util) and the problem does not seem to be happening.

Thanks a lot for any input.

Copied from original issue: katharsis-project/katharsis-core#366

Non-standard getter lookup for Boolean

From @weaselmetal on June 27, 2016 8:25

Hey,
a bug report this time. As per definition of java beans (http://download.oracle.com/otndocs/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/ section 8.3.2) an is-Getter is only expected / allowed for primitive boolean type.
Getters returning reference type Boolean should therefore use the get-prefix.

I'm fine if katharsis would find either version of the getter names, but it breaks when it should find a getter for a Boolean, because it only looks for an is-getter.

Apache BeanUtils also expects get / set prefix for Boolean getters / setters.

Copied from original issue: katharsis-project/katharsis-core#347

Provide useful response at context root to make resources discoverable

From @chabala on July 19, 2016 15:14

When interacting with the jersey-example project, one gets a useful response from a resource URL like tasks:
curl -v http://localhost:8080/tasks/
{"data":[{"type":"tasks","id":"1","attributes":{"name":"First task"},"relationships":{"project":{"links":{"self":"http://localhost:8080/tasks/1/relationships/project","related":"http://localhost:8080/tasks/1/project"},"data":null}},"links":{"self":"http://localhost:8080/tasks/1"}}],"included":[]}

However, at the context root, the response is merely a 500:
curl -v http://localhost:8080/
{"errors":[{"status":"500","title":"Resource error","detail":"Path is empty"}]}

I see the "Path is empty" error originates from here:
https://github.com/katharsis-project/katharsis-core/blob/master/src/main/java/io/katharsis/request/path/PathBuilder.java#L40

What I would prefer is a more HATEOAS style response, with a collection of links to the available resources. Katharsis uses the word HATEOAS on its homepage, but I don't see how the resources are discoverable when the context root returns 500.

If there are suggested workarounds for this, I would be interested to know them as well.

Copied from original issue: katharsis-project/katharsis-rs#41

Transient fields are getting serialised

From @mohlek on June 24, 2016 11:59

I am having a problem with transient fields.
Somehow my transient fields are getting serialized.

@JsonApiResource(type = "user")
public class User {

    @JsonApiId
    @Id
    @Column(name = "ID")
    private Integer             id;

    @Column(name = "USERNAME")
    private String              username;

    @Column(name = "PASSWORD")
    private transient String    password;
...
@JsonApiResourceRepository(User.class)
public class UserEndpoint extends APIEndpoint<User, Integer> {

    @Inject
    private UserTable   userTable;
    @Inject
    private RoleTable   roleTable;

    /**
     * UserEndpoint
     */
    public UserEndpoint() {

    }

    /*
     * (non-Javadoc)
     * @see org.ddg.DDGRestAPI.util.APIEndpoint#findByID(java.io.Serializable)
     */
    @Override
    public User findByID(Integer id) {
        User u = userTable.findByID(id);

        u.setRoles(roleTable.findByUser(id));

        try { // Just for debugging purpose
System.out.println(Modifier.isTransient(u.getClass().getDeclaredField("password").getModifiers()));
        } catch (NoSuchFieldException | SecurityException e) {
            e.printStackTrace();
        }

        return u;
    }
}

Console:

13:51:55,370 INFO  [stdout] (default task-42) true

JSON:

{"data":{"type":"user","id":"1893","attributes":{"password":"aNeatLittleHash",...

Am I missing something? I am using Katharsis 2.4.1

Copied from original issue: katharsis-project/katharsis-core#344

JPA adapter

From @remmeier on June 29, 2016 16:26

is there an interest in a JPA adapter that exposes entities and their relations to JSON API without having to implement anything? I might would look into it if nobody else does.

There is https://github.com/yahoo/elide, but I guess there would be more flexibilty to have a pluggable adapter into katharsis. This pattern might be repeated with other data stores or frameworks like Spring Data.

Copied from original issue: katharsis-project/katharsis-core#349

Katharis should automatically determine Entity/resource names and types

From @chb0github on July 14, 2016 20:53

consider this example code

public static class Foo implements ResourceRepository<Location,Long>{
        @Override
        public Location findOne(Long aLong, QueryParams queryParams) {
            return null;
        }

        @Override
        public Iterable<Location> findAll(QueryParams queryParams) {
            return null;
        }

        @Override
        public Iterable<Location> findAll(Iterable<Long> iterable, QueryParams queryParams) {
            return null;
        }

        @Override
        public <S extends Location> S save(S s) {
            return null;
        }

        @Override
        public void delete(Long aLong) {

        }
    }

   public static void main(String[] args) {
        Foo foo = new Foo();
        Type[] ifaces = foo.getClass().getGenericInterfaces();
        System.out.println(((ParameterizedTypeImpl)ifaces[0]).getActualTypeArguments()[0]);
    }

class com.mz.matrix.model.Location

The entity type can be determined simply by looking at the generics. From this, we can infer a resource by pluralizing and type by lowercasing:

http://host/locations

The @JsonApiResource(type = "locations") is entirely unnecessary; it can be derived. We do, however, want to be able to override it as a type.

We are facing the scenario in 4 seperate places where we need:

public abstract class Location {
   private Long id;
   private String foo;
}

@JsonApiResource(type = "locationtype1")
public class LocationSubType1 extends Location {
   private int age;
}

@JsonApiResource(type = "locationtype2")
public class LocationSubType2 extends Location {
   private long something;
}
POST http://host/locations
{
  "type" : "locationtype1"
}


POST http://host/locations
{
  "type" : "locationtype1" 

}

with mostly different attributes. Basically, without this change, polymorphic payloads become something between impossible and difficult.

I can make the changes if there is no spec-specific reason not to do so

Copied from original issue: katharsis-project/katharsis-core#361

Merge development repositories

From @meshuga on July 24, 2016 13:46

On the last meeting (http://katharsis-jsonapi.readthedocs.io/en/latest/meeting-notes.html#meeting-notes-13-07-2015) it was mentioned to merge the development repositories into one which would allow easy project building.

This issue concerns moving katharsis-parent, katharsis-core, katharsis-rs, katharsis-servlet and katharsis-spring into https://github.com/katharsis-project/katharsis-framework and adjusting them to give possibility to switch to Gradle in the near future.

Copied from original issue: katharsis-project/katharsis-core#371

Annotations to control relationship information

From @danielmischler on July 26, 2016 8:56

There should be annotations to control the information that's included in relationship data, i.e. links, data and/or meta.

According to: http://jsonapi.org/format/#document-resource-object-relationships

This should be independent of what resources are being included (@JsonApiIncludeByDefault).

Example:

{
  "type": "reservations",
  "id": "1",
  "data": {
    "attributes": {},
    "relationships": {
      "event": {
        "data": {
          "type": "events",
          "id": "2"
        }
      }
    }
  }
}

Copied from original issue: katharsis-project/katharsis-core#372

How to update "errors" section without an exception

We have several use cases where validation errors are occurred when a resource is updated via POST or PATCH. According to the 1.0 spec I should be able to add these to the "errors" section of the document.

The way I am reading the documentation, ErrorResponse objects only get processed via an Exception. Validation errors are not an exceptional condition so they shouldn't require an exception. How can I have Katharsis serialize a JSON API Error Object into the "errors" section without an exception?

Support for request filter api

From @remmeier on July 28, 2016 15:3

e.g. servlets and JAX-RS support the implementation of filters that hook in between the incoming request and the actual implementation. Use cases include monitoring/tracing, security, transaction handling, etc. Such a mechanism would be useful for Katharsis as well.

There are probably two different, useful implementations:

  1. filters that are invoked once the incoming request is parsed (e.g. DataBody available)
  2. filters that implement ResourceRepository and wrap the original ResourceRepository

https://github.com/katharsis-project/katharsis-core/pull/370 would provide a module api to register such filters. For https://github.com/katharsis-project/katharsis-core/issues/349 the first type of filter would be useful to setup proper transaction handling.

Based on this also integration into tools like dropwizard metrics or zipkin/brave could be provided.

Copied from original issue: katharsis-project/katharsis-core#375

Passing invaid json results in 500 error

When passing invalid json into request body, JsonParseException is thrown in KatharsisFilterV2.inputStreamBody and than it is caught in KatharsisFilterV2.invoke and handled as 500 error. And looks like there is no possibility to configure this in some other way. I would expect that invalid json results in 400 Bad request.

Id field not found in class

From @Reinardy on April 12, 2016 4:46

Hi

We are trying using katharsis-servlet implementation with OSGI Activator. During the runtime, we are encountered error as Id fields not found in class "Id field not found in class". FYI we are using User.java and we added @JsonApiId. But noticed the ResourceInformaionBuilder is not able to find Id field.

@JsonApiResource(type = "users")
public class User {

@JsonApiId
private String id;

io.katharsis.resource.exception.init.ResourceIdNotFoundException: Id field not found in class: com.sample.domain.model.User
at io.katharsis.resource.information.ResourceInformationBuilder.getIdField(ResourceInformationBuilder.java:153)[331:io.katharsis.core:2.3.0]
at io.katharsis.resource.information.ResourceInformationBuilder.build(ResourceInformationBuilder.java:38)[331:io.katharsis.core:2.3.0]
at io.katharsis.resource.registry.ResourceRegistryBuilder.build(ResourceRegistryBuilder.java:56)[331:io.katharsis.core:2.3.0]
at io.katharsis.resource.registry.ResourceRegistryBuilder.build(ResourceRegistryBuilder.java:41)[331:io.katharsis.core:2.3.0]
at io.katharsis.invoker.KatharsisInvokerBuilder.buildResourceRegistry(KatharsisInvokerBuilder.java:150)[387:io.katharsis.servlet:2.3.0]
at io.katharsis.invoker.KatharsisInvokerBuilder.build(KatharsisInvokerBuilder.java:109)[387:io.katharsis.servlet:2.3.0]
at io.katharsis.servlet.AbstractKatharsisServlet.createKatharsisInvoker(AbstractKatharsisServlet.java:99)[387:io.katharsis.servlet:2.3.0]
at io.katharsis.servlet.AbstractKatharsisServlet.getKatharsisInvoker(AbstractKatharsisServlet.java:81)[387:io.katharsis.servlet:2.3.0]
at io.katharsis.servlet.AbstractKatharsisServlet.service(AbstractKatharsisServlet.java:63)[387:io.katharsis.servlet:2.3.0]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)[82:org.apache.geronimo.specs.geronimo-servlet_3.0_spec:1.0.0]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:69)[93:org.ops4j.pax.web.pax-web-jetty:3.2.5]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:533)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:240)[93:org.ops4j.pax.web.pax-web-jetty:3.2.5]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:75)[93:org.ops4j.pax.web.pax-web-jetty:3.2.5]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.server.Server.handle(Server.java:370)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:971)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1033)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:53)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)[86:org.eclipse.jetty.aggregate.jetty-all-server:8.1.17.v20150415]
at java.lang.Thread.run(Thread.java:745)[:1.7.0_79]

Copied from original issue: katharsis-project/katharsis-servlet#22

Make Katharsis asynchronous

From @meshuga on May 25, 2016 21:19

I want to bring back the thing mentioned in #130 to think about what can be done here. My idea is to allow Katharsis repositories to return a handler that will be called when a result of a method has completed.

Implementing this feature we can allow Katharsis integrate fully with asynchronous toolkits/frameworks like Vert.x, Akka, Play or Ratpack and eventually gain broader variety of users (more innovators and early adopters).

To do that, we need to provide a consistent and easy way to:

  • Allow a user to return a handler which will be called when a response is ready
  • Provide a way of composing multiple handlers from multiple repository methods
  • Distinguish normal and erroneous (containing an Exception) response

On repository side it can be sth like the code below:

@JsonApiResourceRepository(Task.class)
public class TaskRepository {

    @JsonApiFindAll
    public JsonApiResponse findAll() {
        Handler<JsonApiResponse> responseHandler = new Handler<>();
        // process the request and register the handler
        return responseHandler;
    }
}

Such a handler can be later either returned by a controller or composed with other handler(s) in cases like in ResourcePatch, where there are two repository calls.
Each controller will return a Handler<BaseResourceContext> which will be handled by appropriate adapters.

Down below is my list of my propositions to allow asynchronous processing of requests:

  1. Create a Handler class which will contain two methods: handle and handleError and allow returning this class from repositories
  2. Upgrade to Java 8 and allow returning CompletableFuture from repositories
  3. Use RxJava and allow returning Observable from repositories

For me, the first option has the most advantages (no need of Java upgrade, no additional dependencies), but on the other hand it will complicate the code in more sophisticated functionalities like in IncludeLookupSetter.

What do you think about this? I want to start doing this about the next month.

Copied from original issue: katharsis-project/katharsis-core#330

Ability to ensure order of sort parameters

From @collinpeters on July 12, 2016 5:6

Currently the sort mechanism is based on a map which means the order cannot be guaranteed.

So for GET /tasks/?sort[projects][shortName]=desc&sort[users][name][firstName]=asc you cannot guarantee the order is projects.shortName and then name.firstName.

Based on gitter.im discussion with @chb0github, it would be possible to create an implementation based on a TreeMap and reading the true param order from InputStream as HttpServletRequest.getParameterMap is also a map.

Copied from original issue: katharsis-project/katharsis-core#355

Allow katharsis repositories to participate in dependency injection

From @ieugen on July 11, 2016 23:49

I think Katharsis should allow repository creation to be handled by IoC frameworks such as Spring or CDI implementations.

The work should most likely be done in katharsis-spring or other integrations. We have this issue here as it might require changes to katharsis-core .

Please also use this issue to track progress and close it once we have things documented [1]

[1] http://katharsis-jsonapi.readthedocs.io/en/latest/

Copied from original issue: katharsis-project/katharsis-core#354

Serialization of QueryParams for building links

From @Ramblurr on July 15, 2016 22:28

I suspect this is a feature request, but its possible I overlooked a solution.

Given a paginated request, we create the links object like so:

GET /api/people?page[number]=0&page[size]=50

"links": {
    "first": "http://example.com/api/people?page[number]=0&page[size]=50",
    "prev": "http://example.com/api/people?page[number]=0&page[size]=50",
    "next": "http://example.com/api/people?page[number]=1&page[size]=50",
    "last": "http://example.com/api/people?page[number]=100&page[size]=50"
  }

However, once you toss additional QueryParams into the mix, things change. For example with a filter param we would expect:

GET /api/people?page[number]=0&page[size]=50&filter[people][name]=Joe

"links": {
    "first": "http://example.com/api/people?page[number]=0&page[size]=50&filter[people][name]=Joe",
    "prev": "http://example.com/api/people?page[number]=0&page[size]=50&filter[people][name]=Joe",
    "next": "http://example.com/api/people?page[number]=1&page[size]=50&filter[people][name]=Joe",
    "last": "http://example.com/api/people?page[number]=100&page[size]=50&filter[people][name]=Joe"
  }

But as far as I can tell there is no serialization method exposed for transforming QueryParams back into a valid URI string.

Moreover, simply serializing the request's QueryParams wouldn't suffice, because as in this case, I would need to either remove the page params or modify them.

I'm thinking of something like queryParams.getFilters.serialize() (toString() is already taken), or even better:

queryParams.withoutPagination().serialize()

What do you think?

Copied from original issue: katharsis-project/katharsis-core#365

Module API to allow to extend core katharsis functionality

PR to follow soon. Module API was a prerequisite to implement #15. Something similar to the Jackson module api would be beneficial I guess.

  • new Module interface
  • new SimpleModule class as basis for new modules
  • ModuleRegistry holding the various modules and apply there changes to katharsis core
  • registration of new ResourceInformationBuilder
  • registration of new ResourceLookup
  • registration of Jackson modules
  • registration of repositories
  • registration of filters to intercept requests

Created this ticket here to discuss the module part.

Unable to sort by multiple fields on same resource

From @jglatre on May 11, 2016 18:8

Current implementation of SortingParams stores no information about priority of fields, and the current backing data structure (HashMap) doesn't guarantee any predictable order of elements. So I find the whole thing it's only useful when sorting by one field,... or do I miss something?

Copied from original issue: katharsis-project/katharsis-core#309

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.