Writing less code

by Eike DehlingNovember 23, 2016

Have you had that feeling that you have to write too much code to build simple functionality? Some things just feel repetitive, they feel you should be not have to write them yourself, instead a framework should make your life easier.

Recently I’ve been building a project in Java/Spring, and after some time I started wondering about alternatives and how to build the same functionality with less code.

There is lots of alternative frameworks and multiple ways of building rest endpoints in Java/Spring.

  • Building the controller/service/dao layers manually in Spring ; https://spring.io/guides/tutorials/bookmarks/
  • Using spring-data-rest to export your spring-data repositories ; https://spring.io/guides/gs/accessing-data-rest/
  • Groovy/grails RestfulController ; https://examples.javacodegeeks.com/jvm-languages/groovy/grails/grails-rest-example/
  • Python/django django-rest-framework ; http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers/
  • etc

Examples

Below some abbreviated examples of how a simple rest endpoint looks for each approach. To actually run the examples, you’ll need check out the tutorials mentioned earlier. My goal here is a quick comparison of how you do things in each framework.

Java/Spring all manual

Most lines of code needed here. You do have full control though and can easily change all aspects of behavior.

@Entity
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Getter @Setter
    private String firstName;

    @Getter @Setter
    private String lastName;
}


public interface PersonRepository extends
    PagingAndSortingRepository<Person, Long>
{
    // Empty class
}


@RestController
@RequestMapping(path = "/persons")
public class PersonController {
    @Autowired
    PersonRepository personRepository;

    @RequestMapping(method=RequestMethod.GET)
    public void findAll() {
        return personRepository.findAll();
    }

    @RequestMapping(method=RequestMethod.POST)
    public void create(@RequestBody Person person) {
        return personRepository.create(person);
    }

    /**
     * Etc .. repeat the above for each CRUD operation
     */
}


@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

Java/Spring-data-rest

Spring boot and spring-data-rest take a lot of work out of your hands, few actual lines of code are needed. It’s also really nice how adding only a method specification in the controller will (within limits) magically make it available over http.

public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Getter @Setter
    private String firstName;

    @Getter @Setter
    private String lastName;
}


@RepositoryRestResource(collectionResourceRel = "persons", path = "persons")
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> {
    // Empty class
}


@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

Groovy/grails

In groovy/grails, I had write write the fewest lines of code. Simply creating a model and adding the @Resource annotation was it.

@Resource(uri='/persons')
class Person {
    Long id
    String first_name
    String last_name
}

Python/django

In Python, the django-rest-framework allows building rest apis with very little code!

The below code is packed together, normally this distributed between a models, views and urls file. Lookup a django tutorial for the details!

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

class PersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person

class PersonViewSet(viewsets.ModelViewSet):
    queryset = Person.objects.all()
    serializer_class = PersonSerializer

router = routers.SimpleRouter()

router.register(r'persons', PersonViewSet)

Conclusions

I’ve played around with these approaches to get a feeling for them, it seems to me that the more the framework does for you, the less flexible you are. Of course they all have hooks, callbacks and properties to adjust behavior, but it’s never as flexible as building all the blocks yourself.

If the requirements of your project match with the abilities and limitations of one of the code-less frameworks (e.g. simple exposing of Entities over REST) you can save yourself a lot of work in coding (And unit/integration testing !!). I recommend evaluating your options!

I hope this is helpful to some – to me it was quite interesting to investigate the options!

Let me know if you have feedback or suggestions – especially groovy is new to me so might have missed some things there…