Sending body on HTTP GET request

I’ve heard a few times “you can’t, it’s not possible to send a body on a request made with GET method”. Well… You can. You can send a body on a GET request and you can read the body. It’s against the standards and you should not do it, as it will mess your design. But technically, it can be done.

package main

import (
   "encoding/json"
   "io/ioutil"
   "log"
   "net/http"
)

func main() {
   http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
      body, err := ioutil.ReadAll(r.Body)
      if err != nil {
         log.Println(err)
         return
      }

      input := &struct {
         A string `json:"a"`
         B string `json:"b"`
      }{}
      if err := json.Unmarshal(body, input); err != nil {
         log.Println(err)
         return
      }

      data, err := json.Marshal(input)
      if err != nil {
         log.Println(err)
         return
      }
      w.Write(data)
   })

   log.Fatal(http.ListenAndServe(":8118", nil))
}
curl -X GET \
  http://localhost:8118 \
  -H 'content-type: application/json' \
  -d '{"a": "val1", "b":"val2"}'
{"a":"val1","b":"val2"}

Playing with PHP extensions: building a map

I’ve ran into PHP-CPP, a C++ library which helps you build your own PHP extensions in an easier way than writing them from scratch. And I decided to play a little bit. It has good documentation and examples.

Installing is not always out of the box depending on the environment. I like to keep things clean on my working machines so I wanted to have everything in a Docker container, but I quickly ran into an issue installing the library. Fortunately, I’ve found a solution pretty fast.

The first idea that came into my mind was a simple map. Nothing special, I’m not bringing any improvements, I just wanted to convert the following into an extension. Continue reading Playing with PHP extensions: building a map

Race condition on Echo context with GraphQL in Go

Given an API setup with GraphQL and Echo, a colleague ran into a race condition situation. There was a concurrent read/write issue on Echo’s context. GraphQL runs its resolvers in parallel if set so, and when context is shared between resolvers, things can go wrong.

I took a look into Echo’s context implementation and I saw a simple map is used for Get/Set.

For every API call, a handle functions is given an Echo context and executes the GraphQL schema with the specified context.

func handle(c echo.Context) error {
 schema, err := gqlgo.ParseSchema(
  ...
  gqlgo.MaxParallelism(10),
 )

 schema.Exec(
  c,
  ...
 )
}

My solution was to use a custom context which embeds the original one and uses a concurrent map instead of Echo’s. Continue reading Race condition on Echo context with GraphQL in Go

Concurrency in PHP with Swoole

Swoole is a CLI server written in C as a PHP extension. It handles HTTP, TCP and socket servers, offering some really interesting features. The ones I’ve tested and I’m pretty excited about are related to concurrency.

The authors have implemented a concurrency model similar to Go‘s, using coroutines and channels for inter-process communication. It also has a memory map, atomic objects, locks, buffers, timers and others.

I’ve tested their 2.2 version found in PECL, but very recently they’ve release the 4.0.0 version. My enthusiasm suffered a little bit when they’ve introduced a pretty nasty bug with 4.0.0, but they were fast about fixing it, although a new version is not released at the time of writing (but you can compile from master branch).
It’s funny that one day everything was working as expected, and the other day I spent some time until I’ve figured they had just released a new version, and that was causing my issue. I had installed the extension without specifying the version, so a new install got me the latest one.

Below is a very small example of concurrency using routines and a channel. Continue reading Concurrency in PHP with Swoole

Read Go documentation

A few weeks ago I’ve finished reading the Go documentation. The Go 1.10 documentation Android app is very helpful! It’s very easy to read and it has auto bookmarks; whenever you get back into the app, you can return to the chapter you were reading, at the same line you were before closing it.

It was very nice to find out a lot of details. Of course, I don’t remember all of them after just one reading, but when I bump into some situations (performance, how slices really work, libraries, the memory model etc) it’s easier to start researching further if I don’t remember the point exactly.

I don’t want to write Go without understanding as best as I can its way of getting things done.

PHP backward compatibility

Could PHP 7 inherit Go’s philosophy of not introducing breaking changes in future versions? I’ve asked this myself today.

PHP is on a really nice path since version 7, with its courageous changes, and I believe more is yet to come. Because things must evolve, there were some incompatible changes from 5 to 7, and that’s great. And now that it’s more mature, I would like to see more stability and more of those hardcore changes that will keep the language in its good position.

Regarding this, something that I really wish for PHP 7 is to approach Go’s idea of not introducing incompatibilities with future versions. The programs should run flawless when upgrading PHP. It would be a great encouragement for everyone to safely upgrade as soon as a new version is released.

Configurable implementation hidden behind a contract

Some concrete implementations are better to be hidden behind contracts, in a specific package. A layer of abstraction can save you later, mostly on unstable projects that often change requirements, or maybe you just want to test an idea, maybe you don’t have the necessary time to finish a task in a way you’d like to.

A good contract will save you. You can “throw” your implementation behind it and come back later to refine it. Sometimes later means in a few years. But if you’re behind a well designed contract, most probably you’re going to alter only the concrete implementation, without touching large areas of the projects.

I had to filter some user input. Some strings had to be HTML escaped, some sanitized to prevent different attacks. I’ve wrapped everything into a package, behind a contract. For escaping I’ve used Go’s html.EscapeString function, while for sanitizing I’ve found the bluemonday package, which is inspired by an OWASP sanitizier for Java. Continue reading Configurable implementation hidden behind a contract

Using channels to control flow

When I first met channels in Go, I thought they were just data containers. When you want to send data between routines, they are the go to. But later I saw they can be used to control an application flow, like waiting until something happens and only after that go on with the normal flow.

Here’s an approach to wait until some tasks have finished. Let me consider some input data that can come from anywhere: HTTP requests, files, sockets etc. That data can come in fast, but processing can take some time. If the application needs to exit (you restart it, stop it) but you want to wait until all the data you have in memory is processed, you can use channels.

First, I have a routine which processes input data read from a buffered channel. I simulate the slow processing with a sleep. Continue reading Using channels to control flow

Good behavior with bad consequences

Most companies emphasize on good behavior, being friendly to everybody in order to maintain respect and a calm working environment. Which is really great until they don’t speak up and avoid pointing out flaws.

We all have flaws. Not only things that we should improve, but pure flaws, things we don’t do the proper way. Things that we do wrong! And when you’re not told you’re wrong, you’re not going to improve. If you don’t improve, projects suffer.

Now imagine big companies with a lot of people who are not told what to improve, who are overly protected and bad things are hidden from them. Year after year. They have many directions they can’t level up in.

Being told you’re wrong shouldn’t be offensive to you, instead should raise a flag for yourself and make you ask questions, find answers, learn.