GithubHelp home page GithubHelp logo

crudifier's Introduction

Quick setup using generic CRUDs

This library will greatly simplify the process of creating a CRUD interface to the entities of model, allowing to focus in the design itself and removing the need of a graphical user interface or making queries the database to manipulate data, in early development stages.

Requirements

This library is intended to be used using Spring Boot 2.3 and JPA repositories.

How to use

  • Add to POM:
<dependency>
    <groupId>com.github.jobosk</groupId>
    <artifactId>crudifier</artifactId>
    <version>1.3</version>
</dependency>

Note: You might need to add the following repository to pick it up:

<repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
</repository>
  • Define your model entities
  • Define ID resolvers extending: GenericIdResolver<YOUR_ENTITY, YOUR_ENTITYS_ID> (no extra logic required)
  • Indicate ID resolver for each entity with:
@JsonIdentityInfo(
        generator = ObjectIdGenerators.PropertyGenerator.class
        , property = "id"
        , scope = YOUR_ENTITY.class
        , resolver = YOUR_ENTITY_ID_RESOLVER.class
)
  • Define repository interfaces extending: JpaRepository<YOUR_ENTITY, YOUR_ENTITYS_ID>
  • Define service interfaces extending: ICrudService<YOUR_ENTITY, YOUR_ENTITYS_ID>
  • Define service implementations implementing them, and extending: CrudService<YOUR_ENTITY, YOUR_ENTITYS_ID>
  • Declare public constructor for those services:
@Autowired
public YOUR_ENTITY_SERVICE(final YOUR_ENTITY_REPOSITORY repository) {
	super(repository);
}
  • Define controllers (using the URL path mapping of your choice) extending: CrudController<YOUR_ENTITY, YOUR_ENTITYS_ID> (no extra logic required)

  • Add the following bean in any configuration class (to avoid Jackson bug describen below):

@Bean
public Jackson2ObjectMapperBuilderCustomizer addCustomSerializationFeatures() {
	return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.featuresToEnable(
		SerializationFeature.HANDLE_CIRCULAR_REFERENCE_INDIVIDUALLY_FOR_COLLECTIONS
	);
}

Note: If the previous feature does not compile, it means that some other dependency (probably a Spring one, since it comes by default with it) has injected 'jackson-databind' as a transitive dependency (and it does not have the fix for the bug). This can be solved by adding the following dependency before any other that might add the one without the fix:

<dependency>
    <groupId>com.github.jobosk</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11-fix_2791</version>
</dependency>

API

This will simplify the implementation of entity controllers, exposing all the required endpoints with just a few lines of code:

@RestController
@RequestMapping("entity")
public class EntityController extends CrudController<Entity, UUID> {

    @Override
    @GetMapping(ID_PATH)
    @ResponseBody
    public Entity findOne(final @PathVariable(CrudConstant.Http.Param.ID) UUID id) {
        return service.find(id);
    }

    @Override
    @GetMapping
    @ResponseBody
    public Collection<Entity> findAll(final @RequestParam Map<String, String> parameters
            , final HttpServletResponse response) {
        return service.findAll(parameters, response);
    }

    @Override
    @PostMapping
    @ResponseBody
    public Entity create(final @Valid @RequestBody Entity entity) {
        return service.create(entity);
    }

    @PutMapping(ID_PATH)
    @ResponseBody
    public Entity update(final @PathVariable(CrudConstant.Http.Param.ID) UUID id
            , final @RequestBody Map<String, Object> fields) {
        return update(service.find(id), fields);
    }

    @Override
    public Entity update(final Entity entity, final Map<String, Object> fields) {
        return service.update(entity, fields);
    }

    @Override
    @DeleteMapping(ID_PATH)
    public boolean delete(final @PathVariable(CrudConstant.Http.Param.ID) UUID id) {
        return service.delete(id);
    }
}

Create entity

Request:

POST /<entity_mapping>

{
	"name": "new entity"
}

Response:

200:

{
    "id": <UUID>
    , "name": "new entity"
}

Update entity

Request:

PUT /<entity_mapping>/

{
    "name": "edited name of present entity"
}

Response:

200:

{
    "id": <UUID>
    , "name": "edited name of present entity"
}

Delete entity

Request:

DELETE /<entity_mapping>/

Response:

200

Find all entity

Request:

GET /<entity_mapping>[?<filter>][&<filter>...]

filter=

  • <entity attribute>=<value>
  • page=<0..N>
  • size=<1..N>
  • order=[-]<entity attribute>

Note Filtering entity attributes by String values aplies a 'contains' match, whilst numeric values apply an exact match. Also, filters 'page' and 'size' must be both present if one is.

Response:

200:

[
    {
        "id": <UUID>
        , "name": "first present entity"
    }
    , {
        "id": <UUID>
        , "name": "second present entity"
    }
]

Find one entity

Request:

GET /<entity_mapping>/

Response:

200:

{
    "id": <UUID>
    , "name": "present entity"
}

Known bugs

  • Due to the way Jackson handles circular dependencies, serialization of two or more different entities poiting to the same sub-entity will result in the serialization of the sub-entity as an object in the first occurrence and as an ID the following ones.

Known fixed bugs

  • There is a bug in the Jackson serializer mentioned in the following issue:

FasterXML/jackson-databind#2791

The current fix for this bug relies in the presence of the following dependency (within the 'crudifier' library itself, no need to add it again, unless some other dependency includes the one without the fix as a transitive dependency):

<dependency>
    <groupId>com.github.jobosk</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11-fix_2791</version>
</dependency>

To make use of the bug-fixing "functionality", a Jackson configuration bean (indicated in the 'How to' section) is required.

crudifier's People

Contributors

jobosk avatar

Stargazers

Ivan Cordoba avatar

Watchers

James Cloos avatar  avatar

Forkers

alexdefelipe

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.