0

We've standardized on using JSON:API for our REST endpoints, however; not all of our data revolves around repositories and it seems that CRNK requires repositories in order to work.

Is that correct?

Example

I wrote a very simple Spring Boot 2.1.9 example that has a single controller and included CRNK in it, but when I get into my controller I do not get the expected JSON:API output.

Please keep in mind, I am just starting to look at CRNK and this is just a simple "hello world" type of application that I am testing with

Here is my example

package com.example.crnkdemo;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/test/v1.0")
public class Controller {
    @GetMapping(value = "/{country}", produces = "application/vnd.api+json")
    public Country test1(@PathVariable String country, @RequestParam(name = "filter[region]", required = false) String filter) {
        return new Country(country, filter);
    }
}

Country is just a dummy class I created which is:

package com.example.crnkdemo;

import io.crnk.core.resource.annotations.JsonApiId;
import io.crnk.core.resource.annotations.JsonApiResource;

@JsonApiResource(type = "country")
@AllArgsConstructor
@Data
public class Country {

    @JsonApiId
    private String country;
    private String region;

Results

But when I use the following URL http://localhost:8080/test/v1.0/US?filter[region]=northeast I get

{
    "country": "US",
    "region":"northeast"
}

I would have expected the JSON API type of result

{
  "data": {
    "type": "country",
    "id": "US",
    "attributes": {
      "region": "northeast"
    }
}

Thanks!

Jim M.
  • 909
  • 1
  • 12
  • 29

3 Answers3

0

I ran into similar issue and the problem was that I got io.crnk:crnk-format-plain-json in my dependencies (simply copied from an example app) which changes the way how the responses look like (non-JSON-API). So first have a look into your maven/gradle configuration.

  • Thanks for taking the time to reply. That doesn't appear to be my issue, I am using implementation 'io.crnk:crnk-setup-spring-boot2:3.0.20190714142556' implementation 'io.crnk:crnk-home:3.0.20190714142556' And none of the dependencies loaded was the plain json one. – Jim M. Nov 07 '19 at 17:34
0

"not all of our data revolves around repositories"

you may also have a look at http://www.crnk.io/releases/stable/documentation/#_architecture where the architecture of resource-oriented framework like Crnk and JSON:API are discussed in more detail. In principle one can model everything as repository. Applications usually follow two kinds of patterns: CRUD ones and "actions". CRUD is simple: GET, POST, PATCH, DELETE objects. A repository is a perfect match for that. In contrast, people have a harder time when it comes to "actions". But this can be modelled as well as CRUD. For example, POSTing an AddressChange resource may trigger a server to start modifying the address(es) of some objects. This may happend immediately or take a longer time. Subsequent GET requests for the POSTed resources will reveal the current status of the action. And a DELETE request can cancel the request.

Crnk itself is not in need for Controllers as Spring MVC is. This kind of "lower-level plumbing" is taken care by Crnk itself because JSON:API specifies how a REST layer is supposed to look like. So there is no need to write custom code to specify urls patterns, parameters, etc. as in the MVC example above. Instead one can implement a repository:

public class TaskRepositoryImpl extends ResourceRepositoryBase<Task, Long>  {

  private ConcurrentHashMap<Long, Task> tasks = new Concurrent...

  public TaskRepositoryImpl() {
    super(Task.class);
  }


  @Override
  public <S extends Task> S create(S entity) {
    map.put(entity.getId(), entity);
    return entity;
  }


  @Override
  public ResourceList<Task> findAll(QuerySpec querySpec) {
    return querySpec.apply(tasks.values());
  }

  ...

}

There are also many built-in defult repository implementatons like for in-memory, JPA, security to cover the most frequent use cases.

Remo Meier
  • 141
  • 2
0

with crnk, no need of writing controllers, manager classes. By default the controllers are defined. Once we define the resources, we can access it by http://server_name:portno/crnk-path-prefix-property/defined_resourcename & the method type

Eg. In our case, resource is country, let's say server is running in localhost:8081 and crnk-path-prefix is /api/v1, then the url is http://localhost:8081/api/v1/country & set method type is GET, it will give the desired output. Remember to set content-type as application/vnd.api+json.

For POST, same url and set method type as POST, pass the data object For PATCH, same url along with id attribute appended to the url and set method type as PATCH & pass the data object