A very basic REST service for JSON data - enough for prototyping and MVPs!

caffeine - minimum viable backend

A very basic REST service for JSON data - enough for prototyping and MVPs!

Features:

  • no need to set up a database, all data is managed automagically*
  • REST paradigm CRUD for multiple entities/namespaces
  • schema validation
  • search using jq like syntax (see https://stedolan.github.io/jq/manual/)
  • CORS enabled
  • easy to deploy as container

* you can use an in-memory data approach with zero config or postgres as database, you just need an instance running, no queries/sql/worries!

For a sample Vue app using caffeine see: https://gist.github.com/calogxro/6e601e07c2a937df4418d104fb717570

How to

Simply start the server with:

go run caffeine.go

optionally provide -ip_port param, default is :8000

Store a new "user" with an ID and some json data:

> curl -X POST -d '{"name":"jack","age":25}'  http://localhost:8000/ns/users/1
{"name":"jack","age":25}

the value will be validated, but it could be anything (in JSON!)

retrieve later with:

> curl http://localhost:8000/ns/users/1
{"name":"jack","age":25}

All operations

Insert/update

> curl -X POST -d '{"name":"jack","age":25}'  http://localhost:8000/ns/users/1
{"name":"jack","age":25}

Delete

> curl -X DELETE http://localhost:8000/ns/users/1

Get by ID

> curl http://localhost:8000/ns/users/1
{"name":"jack","age":25}

Get all values for a namespace

> curl http://localhost:8000/ns/users | jq 
[
  {
    "key": "2",
    "value": {
      "age": 25,
      "name": "john"
    }
  },
  {
    "key": "1",
    "value": {
      "age": 25,
      "name": "jack"
    }
  }
]

Get all namespaces

> curl http://localhost:8000/ns
["users"]

Delete a namespace

> curl -X DELETE http://localhost:8000/ns/users
{}

Search by property (jq syntax)

> curl http://localhost:8000/search/users?filter="select(.name==\"jack\")"  | jq
{
  "results": [
    {
      "key": "1",
      "value": {
        "age": 25,
        "name": "jack"
      }
    }
  ]
}

Schema Validation

You can add a schema for a specific namespace, and only correct JSON data will be accepted

To add a schema for the namespace "user", use the one available in schema_sample/:

curl --data-binary @./schema_sample/user_schema.json http://localhost:8000/schema/user

Now only validated "users" will be accepted (see user.json and invalid_user.json under schema_sample/)

Run as container

docker build -t caffeine .

and then run it:

docker run --publish 8000:8000 caffeine

Run with Postgres

First run an instance of Postgres (for example with docker):

docker run -e POSTGRES_USER=caffeine -e POSTGRES_PASSWORD=mysecretpassword -p 5432:5432 -d postgres:latest

Then run caffeine with the right params to connect to the db:

DB_TYPE=postgres PG_HOST=0.0.0.0 PG_USER=caffeine PG_PASS=mysecretpassword go run caffeine.go

(params can be passed as ENV variables or as command-line ones)

A very quick to run both on docker with docker-compose:

docker-compose up -d
Comments
  • Added Swagger/OpenAPI endpoint

    Added Swagger/OpenAPI endpoint

    Hi there, great little utility.

    I added an endpoint to return a swagger spec.

    To see it in action first, ensure there is at least one namespace, i.e.:

    > curl -X POST -d '{"name":"jack","age":25}'  http://localhost:8000/ns/users/1
    {"name":"jack","age":25}
    
    

    Then, if you make the following request, you will get back a swagger spec for the server, which lists all the supported operations for the known namespaces:

    curl -X GET http://localhost:8000/openapi.json
    

    You can then paste the JSON here, https://editor.swagger.io and even use it interactively.

    I also added an error type, DbError, so I could return more detailed error information. My goal with that is that the server should only return a 400 if the request was indeed a bad request.

    My thinking there is that if you do a GET for example and the namespace doesn't exist, that's a 400, but if the id simply isn't in the table, then that's a 404.

    The code is still a bit rough. I would welcome feedback.

    NOTE: In the future, if the user is using schemas, we can also add the schema to the Swagger output.

  • File based database

    File based database

    I want to develop a feature to use file system as data storage. It is similar to the mem implementation except that the data is persisted easily on disk. To be honest, I think pg is kinda overkill.

    In terms of security (e.g. namespaces named like /test/../../../ssh.conf) we should prohibit names with slashes and dots. Although if caf is used inside a container (mounted directory) this problem won't be a valid concern anymore...

  • Swagger schemas

    Swagger schemas

    If a namespace includes a schema, include it in the swagger definition.

    This causes swagger-ui to populate the Example Value/Schema fields. It also causes it to provide a pre-populated sample value when performing a POST operation.

    More importantly, it would allow code generation tools to create domain objects for the namespaces.

    At the moment the schema is attached to the following endpoints:

    GET /ns/example/ GET /ns/example/{id} POST /ns/example/{id} GET /search/example

    ⚠️NOTE: This only works for simple schemas. JSON schema and OpenAPI are syntactically very similar, but there are differences. See: https://github.com/wework/json-schema-to-openapi-schema. I should probably create a mechanism to exclude a schema from swagger, in case we ever have to use a schema which is incompatible with swagger.

    Only lightly tested so far. Comments and suggestions welcome.

  • client generation?

    client generation?

    Great project!

    I plan to use this eventually, but if i'm going to design a service, I need both client and server. I'd rather not have to spec out both if possible.

    It'd be cool if you could generate a swagger or protobuf definition from existing data and schema. I'm sure that's a lot of work but it'd be much more powerful to have strictly typed objects in the client.

  • CI/CD and built releases

    CI/CD and built releases

    We can add a circle ci or travis to this project. so that:

    • verify that tests are passing
    • measure test coverage
    • publish binary releases
    • publish to package managers (far future)
  • Auto JWT

    Auto JWT

    We can generate JWT secrets at startup and store them in our storage. JWT would be out of the box.

    (I know storing secrets in storage is not recommended. but this program is not intended to be used in production environments.)

  • Lets add a few static routes for auth

    Lets add a few static routes for auth

    Now that we have JWT implemented here, I think we can add a few routes to achieve these:

    • register new user (signup)
      • full name
      • username
      • password
    • get a jwt with expire time
      • username
      • password
    • refresh jwt
      • token (as header)

    If you agreed, I would open a MR soon.

    Please note that we need to sacrifice user model flexibility to implement a reliabe API. This flaw can be remedied in future MRs.

  • Wrong status code for not existing namespace

    Wrong status code for not existing namespace

    Requests (GET, DELETE) for not existing namespaces return a 400 error: a 404 error would be expected. Moreover, on deleting a not existing namespace two objets are returned: {"error": "not found"} and {}.

    $ curl localhost:8000/ns
    []
    

    GET

    $ curl -v localhost:8000/ns/todos
    *   Trying 127.0.0.1:8000...
    * TCP_NODELAY set
    * Connected to localhost (127.0.0.1) port 8000 (#0)
    > GET /ns/todos HTTP/1.1
    > Host: localhost:8000
    > User-Agent: curl/7.68.0
    > Accept: */*
    > 
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 400 Bad Request
    < Content-Type: application/json
    < Vary: Origin
    < Date: Fri, 19 Nov 2021 14:27:00 GMT
    < Content-Length: 22
    < 
    * Connection #0 to host localhost left intact
    {"error": "not found"}
    

    DELETE

    $ curl -v -X DELETE localhost:8000/ns/todos
    *   Trying 127.0.0.1:8000...
    * TCP_NODELAY set
    * Connected to localhost (127.0.0.1) port 8000 (#0)
    > DELETE /ns/todos HTTP/1.1
    > Host: localhost:8000
    > User-Agent: curl/7.68.0
    > Accept: */*
    > 
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 400 Bad Request
    < Content-Type: application/json
    < Vary: Origin
    < Date: Fri, 19 Nov 2021 14:31:01 GMT
    < Content-Length: 24
    < 
    * Connection #0 to host localhost left intact
    {"error": "not found"}{}
    
  • Wrong status code on not found

    Wrong status code on not found

    You can reproduce it like this:

    $ curl -v http://localhost:8000/ns/users/1
    *   Trying ::1:8000...
    * Connected to localhost (::1) port 8000 (#0)
    > GET /ns/users/1 HTTP/1.1
    > Host: localhost:8000
    > User-Agent: curl/7.77.0
    > Accept: */*
    > 
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 400 Bad Request
    < Content-Type: application/json
    < Vary: Origin
    < Date: Thu, 18 Nov 2021 10:58:22 GMT
    < Content-Length: 22
    < 
    * Connection #0 to host localhost left intact
    {"error": "not found"}
    

    Need to change status to 404.

Rest-and-go-master - A basic online store API written to learn Go Programming Language
Rest-and-go-master - A basic online store API written to learn Go Programming Language

rest-and-go(Not maintained actively) A basic online store API written to learn G

Jan 12, 2022
REST API made using native Golang libraries. This API resembles the basic working of Instagram.
REST API made using native Golang libraries. This API resembles the basic working of Instagram.

Golang RESTful API for Instagram A Go based REST API built using native libraries. The API has been thoroughly worked through with Postman. Routes inc

Mar 16, 2022
TeslaMateApi is a RESTful API to get data collected by self-hosted data logger TeslaMate in JSON

TeslaMateApi is a RESTful API to get data collected by self-hosted data logger TeslaMate in JSON.

Dec 10, 2022
REST Layer, Go (golang) REST API framework
REST Layer, Go (golang) REST API framework

REST Layer REST APIs made easy. REST Layer is an API framework heavily inspired by the excellent Python Eve. It helps you create a comprehensive, cust

Dec 16, 2022
A REST web-service sample project written in Golang using go-fiber, GORM and PostgreSQL

backend A REST web-service sample project written in Golang using go-fiber, GORM and PostgreSQL How to run Make sure you have Go installed (download).

Jan 1, 2023
mini json response for rest api

You will avoid commands below defining every time in services. resp := Response{ Code: responseCode, Message: msg, Data: data, } http.ResponseWriter.W

Dec 7, 2021
🥒 Simple REST-API product service (download products in .csv file)

?? Simple REST-API product service (download products in .csv file)

Nov 28, 2021
An app skeleton for very simple golang web applications

Golang App Skeleton This is a skeleton for a golang web application optimized for simplicity and rapid development. Prerequisites Go 1.15 or greater O

Oct 16, 2022
Example of REST API to collect simple data

Statistics Collector An example of REST API to collect views statistics How to build There is Docker file you can set TARGET_OS and TARGET_ARCH to com

Dec 6, 2021
Go-userapi-rest - Build a RESTful API that can get/create/update/delete user data from a persistence database

GO ASSIGNMENT Overview of the Task Context Build a RESTful API that can get/crea

Sep 6, 2022
REST api using fiber framework written in golang and using firebase ecosystem to authentication, storage and firestore as a db and use clean architecture as base
REST api using fiber framework written in golang and using firebase ecosystem to authentication, storage and firestore as a db and use clean architecture as base

Backend API Example FiberGo Framework Docs : https://github.com/gofiber Info This application using firebase ecosystem Firebase Auth Cloud Storage Fir

May 31, 2022
Building basic API with go, gin and gorm

Project Description Terima kasih sudah berkunjung ke halaman repositori ini, repositori ini berisi basic RESTFUL API dengan menggunakan teknologi seba

Nov 20, 2021
Short basic introduction to Go programming language.
Short basic introduction to Go programming language.

Go, Go! Short basic introduction to Go v1.17.6 programming language Go Logo is Copyright 2018 The Go Authors. All rights reserved. About This work was

May 30, 2022
A small and evil REST framework for Go

go-rest A small and evil REST framework for Go Reflection, Go structs, and JSON marshalling FTW! go get github.com/ungerik/go-rest import "github.com/

Dec 6, 2022
Go WhatsApp REST API Implementation Using Fiber And Swagger
Go WhatsApp REST API Implementation Using Fiber And Swagger

Go WhatsApp REST API Implementation Using Fiber And Swagger Package cooljar/go-whatsapp-fiber Implements the WhatsApp Web API using Fiber web framewor

May 9, 2022
REST API boilerplate built with go and clean architecture - Echo Framework

GO Boilerplate Prerequisite Install go-migrate for running migration https://github.com/golang-migrate/migrate App requires 2 database (postgreSQL an

Jan 2, 2023
Example Golang API backend rest implementation mini project Point Of Sale using Gin Framework and Gorm ORM Database.

Example Golang API backend rest implementation mini project Point Of Sale using Gin Framework and Gorm ORM Database.

Dec 23, 2022
Go REST API - Bucket list - built with go-chi, Docker, and PostgreSQL

Go REST API - Bucket list - built with go-chi, Docker, and PostgreSQL Requirements Docker and Go golang-migrate/migrate Usage Clone the repository wit

Dec 14, 2021
Simple REST-API implementation using Golang with several packages (Echo, GORM) and Docker

Simple REST-API Boilerplate This is a simple implementation of REST-API using Golang and several packages (Echo and GORM). By default, I use PostgreSQ

Sep 13, 2022