"Code with an appeal."

At tech.reBuy we pursue to build software we can show off to our friends. It should give you some goose bumps and a quality the team can be proud of.

We believe that user experience depends on the software we forge, which is why the code needs to excel. The whole architecture should be fun to use, fast, rock solid and simply state of the art.

These standards are hard to reach but we try our best to stay hungry and foolish for more. We hope you feel the same way and join us on this challenging journey.

hubot approved

Hubot, employee of the month.

Technologies we use

"Use the right tool for the problem" is one of the many mantras we live by. Over the years, this mindset has created a great diversity of skills as can be seen by our handpicked tech stack. Here's a preview of some of them.

  • php
    • symfony3.4
    • phpunit
    • codeception
    • mink
    • Doctrine
    • composer
    • silex
    • Zend_Framework_1
  • java
    • Spring
    • Spring_Boot
    • Hibernate
    • flyway
    • junit
    • mockito
    • Maven
  • scala
    • play!
    • Akka
    • Scalatest
    • sbt
    • Kafka
  • kotlin
    • Retrofit
    • rxjava2
    • Dagger
    • Glide
    • Fragmentation
    • Paper
    • FlexibleAdapter
    • ReactiveNetwork
    • nunit
    • fastlane
  • swift
    • Alamofire
    • Swinject
    • RxSwift
    • RxCocoa
    • fastlane
  • noteworthy
    • some_ruby
    • some_python
  • javascript
    • TypeScript
    • Angular6
    • AngularJS
    • jasmine
    • jest
    • karma
    • webpack
    • npm
  • css
    • Twitter_Bootstrap
    • Sass
    • BEM
  • server
    • nginx
    • RabbitMQ
    • MySQL
    • PostgreSQL
    • Solr
    • MongoDB
    • memcached
    • kafka
  • devops
    • Kubernetes
    • AWS
    • Golang
    • CoreOS_Container_Linux
    • Terraform
    • Docker
    • Vagrant
  • monitoring
    • prometheus
    • graylog
    • logstash
    • nagios
    • New_Relic
  • tooling
    • github
    • jenkins
    • TravisCI
    • HipChat
    • hubot
    • jira
    • IntelliJ
    • mac
    • windows
    • linux

Onward & Upward To Greater Glory!

We aim high

Rapid growth is challenging. It reveals problems we've never dreamt of. But it's a challenge we are lucky to have. Therefore, high scalability is our primary goal. We have still a long way to go but why aim for less?

Constant change

Technology evolves fast, and standing still is not an option. Applying new solutions or improved versions of existing software is a fundamental part of change. Adopting early is an option if it's worth the effort. Who doesn't love new shiny things?

reach for more


reVolution

In general we divide our story into multiple parts: the dark, the bright and the shiny.

The Dark

The dark story is about PHP, MySQL with full text search and everything in one big pile of code. It's monolithic, cumbersome, and slow to develop. It worked well for quite some time, but we knew that at some point we would not be able to keep this going. All software ran on a bunch of machines that were provisioned and maintained by hand.

So let's fast forward to the bright story.

The Bright

We migrated most of the components into a service-oriented architecture. We develop most of the things you see on rebuy.de.

Our new services usually have two communication methods. Each service offers a RESTish API for synchronous calls. Additionally, they interconnect via RabbitMQ for an asynchronous information flow.

Our services have evolved quite differently. There are very new and shiny ones, based on Spring 4, Spring Boot and PostgreSQL. They are completely isolated from each other. Also, there are some older ones, utilizing Spring 3, which share the same database with other services.

We managed to put most of server provisioning into Puppet code. This also helped us to create sandbox environments on a VMware cluster and on the developer machines with Vagrant. Though, adding new services or machines still required a lot of manual work.

At last, we have a few very old PHP based services. Those are some of the oldest services that are still in use. Our big plan™ is to finally migrate the last services away from the dark times and only use isolated services.

The Shiny

The next big step was to migrate away from a static number of manually provisioned machines and into the cloud. This has the advantage that we can add capacity on demand (eg for TV spots) and we are able to automate everything.

We created a Kubernetes cluster on AWS and are using Terraform for provisioning it. This means our whole infrastructure is checked into source control which makes all changes comprehensible and reproducible.

Using Kubernetes improved our failure handling in a big way. All of our critical services are highly available, since the count of replicas of a single service is only a matter of changing a number in the configuration. Failures of single replicas get handled by Kubernetes, which restarts the service. This resolves the issue in the most cases and the developers can take a look into the problem the next day. Even failures of whole AWS instances get handled well, because Kubernetes just migrates the replicas to working instances and AWS recreates the nodes, which automatically join the Kubernetes cluster.

The new infrastructure also makes it trivial for developers to create new services. With that comes the advantage of being able to split big and complex services into smaller ones. Additionally, it got a lot easier to create a staging environment, that is almost identical to the production cluster and deploy the applications there to test them. Automating the cluster creation for our development teams will be the next step in our story.

Service oriented architecture

Truly RESTful

Take a look at the customer-silo API documentation,
autogenerated from the java source code.

customer-silo API

A condensed journey through our system

When a customer creates an order, there are several components at work:

  • rebuy-blue (frontend, php)
  • order-service
  • payment-service
  • email-service
  • erp (php, rest of the monolith, from the dark times)
  • customer-service
  • shipping-service

The rebuy-blue frontend constructs a json dto from the provided information and transfers them to the order-service by consuming its REST api. After the order-service has ensured validity of the involved data, the order will be created:

  • Item(s) sellable? Check.
  • Correct address? Check.
  • Voucher valid? Check.
  • create order

After committing the transaction to the database, one OrderCreatedMessage and multiple OrderItemCreatedMessages are published to our RabbitMQ message bus.

To recalculate the availability of each item, our ERP consumes all OrderItemCreatedMessages. We bridge the dark and light times with our own PHP AMQP library.

The payment-service is subscribed to the OrderCreatedMessage to check for a valid payment. In case of direct payment methods (e.g. credit card or paypal), the order becomes immediately ready for shipping.

In parallel, the email-service reacts to the order creation, aggregates the data required for the charming "Your order has been created" email and sends it to our lovely customer.

Once the order has been created and the system has received a payment confirmation the goods are ready for pick and pack.

Since our logistics handles thousands of shippable orders a day, we have a fully automated process for creating the appropriate shipping label for every package.

An OrderShippedMessage is published onto RabbitMQ from our shipping-service as soon as the order ships. The ERP steps in once more and closes the order.

Finally, the billing-service creates the invoice as the OrderClosedMessage is published onto RabbitMQ.

And all this happened due to one user click.

We do not fear to refactor

In these times, quick progression is key and we still have a lot of darkness to banish. In order to reach this goal we've learned to let go of the past and do complete refactorings step by step instead of glueing the remnants back together.

Modern

We try to move past the medieval times as effectively as possible. Our stack is no exception to that: Java 8 streams? Check. PHP7 type hinting? Got that. Mono c# 6 support? Yep! All the great features you desire are at your disposal.

Automation is king

Automated processes help us with repetitive daily tasks ranging from deployment, to data creation, error reporting or testing. Besides that, processes defined in code never lie and make us giggle like little girls when they work their magic.

Unit tests

At tech.reBuy, unit tests are not just about code coverage. They enable us to do reckless refactorings and help us detecting design fubars in our software. Therefore, tests are necessary for every software solution we roll out.

We believe in open source

"Build software better, together." - github

We enjoy learning from others and exchanging knowledge is a key part of our daily work. We embrace open source models because it's the right tool to encourage this behavior.

Besides contributing, we slowly venture into maintaining our own projects. Why don't you join us on our journey?