rest-layer: Storer Interface time.Now() for Created and Updated fields return unsupported time formats

Introduction:

Using the REST Layer to build a large scale API for commercial product, we have reached a point to build our own Storer interface for PostgreSQL, heavily inspired by the SQLite and MongoDB implementations we have been able to succesfuly produce the following storage “add-on” (for PostgreSQL, but it can be easily ported to any SQL-based database) and are happily to opensource it for the community: https://github.com/SAFAD/rest-layer-pgsql

Issue :

We have faced an issue with the Storer interface where using the pointer to resource.Item struct to pull the created/updated fields we receive wrong time.Time format as following: 2018-02-27 23:07:44.4179416 +0100 CET m=+7.679574500 where m=+7.679574500 is additional string that is appearing from nowhere, and causing the entire API to panic when trying to format it/use it in database queries

Reproduction:

Use the storage handler mentioned above, and add a logger or simply print the resource.Item data

Results:

Mis-formatted time.Time data

Expected results:

Correct time.Time data that is able to be parsed and formatted with time.Parse/time.Format

Conclusion:

We have been able to workaround this bug for now using a hack but it is not good for code quality or maintainability.

We would also love to hear your input on the library provided above and if anything missing or needs to be fixed.

Best Regards

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 2
  • Comments: 17 (6 by maintainers)

Most upvoted comments

Regarding the pgsql module, it’s awesome! Thanks fort the contrib. Feel free to send a PR to add its reference to the README.

Some feedback:

  • There are some SQL injections opportunity:
  • Using LIKE on equality (see utils.go#L83) is breaking the REST Layer API. Pattern matching should only be enabled when $regex is used.
  • At utils.go#L52, it would be more efficient to store substrings in a slice and use strings.Join (or to use a bytes.Buffer).
  • Same remark for most of string concats in the rest of the function.
  • Same remark in valueToString and valuesToString.
  • At pgsql.go#L58, rowVals and rowValsPtr could be reused for each lines to avoid allocation.
  • At pgsql.go#L279, do a[:len(a)-1] = ")" (same for next line) to avoid two allocations.

we have been able to succesfuly produce the following storage “add-on” for PostgreSQL […] and are happily to opensource it for the community: https://github.com/SAFAD/rest-layer-pgsql

Awesome 😃

where m=+7.679574500 is additional string that is appearing from nowhere, and causing the entire API to panic when trying to format it/use it in database queries

It’s not appearing from nowhere, it’s the Go monotonic time component added in Go 1.9 https://golang.org/doc/go1.9#monotonic-time.

It can be stripped away by calling Truncate(0) on the time object before serializing it and/or by setting intial values to time.Now().Truncate(0) instead of time.Now().

I suppose in rest-layer we should update schema.Now to call Truncate(0):

https://github.com/rs/rest-layer/blob/a468556f73fd817100bf3b2a2d07dcf4ee19d1df/schema/time.go#L13