@Override
  public final BaseResponse<?> handle(
      JsonPath jsonPath, RequestParams requestParams, RequestBody requestBody) throws Exception {
    String resourceName = jsonPath.getResourceName();
    PathIds resourceIds = jsonPath.getIds();
    RegistryEntry registryEntry = resourceRegistry.getEntry(resourceName);

    if (registryEntry == null) {
      throw new ResourceNotFoundException(resourceName);
    }
    if (requestBody == null) {
      throw new RequestBodyNotFoundException(HttpMethod.POST, resourceName);
    }

    Serializable castedResourceId = getResourceId(resourceIds, registryEntry);
    ResourceField relationshipField =
        registryEntry
            .getResourceInformation()
            .findRelationshipFieldByName(jsonPath.getElementName());
    if (relationshipField == null) {
      throw new ResourceFieldNotFoundException(jsonPath.getElementName());
    }
    ResourceRepository resourceRepository = registryEntry.getResourceRepository();
    @SuppressWarnings("unchecked")
    Object resource = resourceRepository.findOne(castedResourceId, requestParams);

    Class<?> baseRelationshipFieldClass = relationshipField.getType();
    Class<?> relationshipFieldClass =
        Generics.getResourceClass(relationshipField.getGenericType(), baseRelationshipFieldClass);
    @SuppressWarnings("unchecked")
    Class<? extends Serializable> relationshipIdType =
        (Class<? extends Serializable>)
            resourceRegistry
                .getEntry(relationshipFieldClass)
                .getResourceInformation()
                .getIdField()
                .getType();

    RelationshipRepository relationshipRepositoryForClass =
        registryEntry.getRelationshipRepositoryForClass(relationshipFieldClass);
    if (Iterable.class.isAssignableFrom(baseRelationshipFieldClass)) {
      if (!requestBody.isMultiple()) {
        throw new RequestBodyException(HttpMethod.POST, resourceName, "Non-multiple data in body");
      }
      Iterable<DataBody> dataBodies = requestBody.getMultipleData();
      processToManyRelationship(
          resource,
          relationshipIdType,
          jsonPath.getElementName(),
          dataBodies,
          relationshipRepositoryForClass);
    } else {
      if (requestBody.isMultiple()) {
        throw new RequestBodyException(HttpMethod.POST, resourceName, "Multiple data in body");
      }
      DataBody dataBody = requestBody.getSingleData();
      processToOneRelationship(
          resource,
          relationshipIdType,
          jsonPath.getElementName(),
          dataBody,
          relationshipRepositoryForClass);
    }

    MetaInformation metaInformation =
        getMetaInformation(resourceRepository, Collections.singletonList(resource), requestParams);

    return new ResourceResponse(metaInformation);
  }
  @Test
  public void onExistingToOneRelationshipShouldRemoveIt() throws Exception {
    // GIVEN
    RequestBody newTaskBody = new RequestBody();
    DataBody data = new DataBody();
    newTaskBody.setData(data);
    data.setType("tasks");
    data.setAttributes(OBJECT_MAPPER.createObjectNode().put("name", "sample task"));
    data.setRelationships(new ResourceRelationships());

    JsonPath taskPath = pathBuilder.buildPath("/tasks");
    ResourcePost resourcePost = new ResourcePost(resourceRegistry, typeParser, OBJECT_MAPPER);

    // WHEN -- adding a task
    BaseResponseContext taskResponse =
        resourcePost.handle(taskPath, new QueryParams(), null, newTaskBody);

    // THEN
    assertThat(taskResponse.getResponse().getEntity()).isExactlyInstanceOf(Task.class);
    Long taskId = ((Task) (taskResponse.getResponse().getEntity())).getId();
    assertThat(taskId).isNotNull();

    /* ------- */

    // GIVEN
    RequestBody newProjectBody = new RequestBody();
    data = new DataBody();
    newProjectBody.setData(data);
    data.setType("projects");
    data.setAttributes(OBJECT_MAPPER.createObjectNode().put("name", "sample project"));

    JsonPath projectPath = pathBuilder.buildPath("/projects");

    // WHEN -- adding a project
    ResourceResponseContext projectResponse =
        resourcePost.handle(projectPath, new QueryParams(), null, newProjectBody);

    // THEN
    assertThat(projectResponse.getResponse().getEntity()).isExactlyInstanceOf(Project.class);
    assertThat(((Project) (projectResponse.getResponse().getEntity())).getId()).isNotNull();
    assertThat(((Project) (projectResponse.getResponse().getEntity())).getName())
        .isEqualTo("sample project");
    Long projectId = ((Project) (projectResponse.getResponse().getEntity())).getId();
    assertThat(projectId).isNotNull();

    /* ------- */

    // GIVEN
    RequestBody newTaskToProjectBody = new RequestBody();
    data = new DataBody();
    newTaskToProjectBody.setData(data);
    data.setType("projects");
    data.setId(projectId.toString());

    JsonPath savedTaskPath = pathBuilder.buildPath("/tasks/" + taskId + "/relationships/project");
    RelationshipsResourcePost relationshipsResourcePost =
        new RelationshipsResourcePost(resourceRegistry, typeParser);

    // WHEN -- adding a relation between task and project
    BaseResponseContext projectRelationshipResponse =
        relationshipsResourcePost.handle(
            savedTaskPath, new QueryParams(), null, newTaskToProjectBody);
    assertThat(projectRelationshipResponse).isNotNull();

    // THEN
    TaskToProjectRepository taskToProjectRepository = new TaskToProjectRepository();
    Project project = taskToProjectRepository.findOneTarget(taskId, "project", REQUEST_PARAMS);
    assertThat(project.getId()).isEqualTo(projectId);

    /* ------- */

    // GIVEN
    RelationshipsResourceDelete sut = new RelationshipsResourceDelete(resourceRegistry, typeParser);

    // WHEN -- removing a relation between task and project
    BaseResponseContext result =
        sut.handle(savedTaskPath, new QueryParams(), null, newTaskToProjectBody);
    assertThat(result).isNotNull();

    // THEN
    assertThat(result.getHttpStatus()).isEqualTo(HttpStatus.NO_CONTENT_204);
    Project nullProject = taskToProjectRepository.findOneTarget(taskId, "project", REQUEST_PARAMS);
    assertThat(nullProject).isNull();
  }