Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
R

rest-layer

> 后端框架
Open source

REST Layer, Go (golang) REST API framework

1.2K stars0 likes0 views
WebsiteGitHub

About

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, customizable, and secure REST (graph) API on top of pluggable backend storages with no boiler plate code so you can focus on your business logic.

Implemented as a net/http handler, it plays well with standard middleware like CORS. It is also context aware. This allows deadline management to be supported down to the storage and permit an easy extensibility by passing custom data between layers of the framework.

REST Layer is an opinionated framework. Unlike many API frameworks, you don't directly control the routing and you don't have to write handlers. You just define resources and sub-resources with a schema, the framework automatically figures out what routes need to be generated behind the scene. You don't have to take care of the HTTP headers and response, JSON encoding, etc. either. REST layer handles HTTP conditional requests, caching, integrity checking for you.

A powerful and extensible validation engine make sure that data comes pre-validated to your custom storage handlers. Generic resource handlers for MongoDB, ElasticSearch and other databases are also available so you have few to no code to write to get up and running.

Moreover, REST Layer let you create a graph API by linking resources between them. Thanks to its advanced field selection syntax or GraphQL support, you can gather resources and their dependencies in a single request, saving you from costly network round-trips.

The REST Layer framework is composed of several sub-packages:

Package Coverage Description
rest A net/http handler to expose a REST-ful API.
graphql A net/http handler to expose your API using the GraphQL protocol.
schema A validation framework for the API resources.
resource Defines resources, manages the resource graph and manages the interface with resource storage handler.

Documentation

  • Breaking Changes
  • Features
    • Extensions
    • Main Storage Handlers
    • Alternate Storage Handlers
  • Usage
  • Resource Configuration
    • Schema
    • Field Definition
    • Binding
    • Modes
    • Hooks
    • Sub Resources
    • Dependency
  • HTTP Request Headers
    • Prefer
  • HTTP Request Methods
    • OPTIONS
    • HEAD
    • GET
    • POST
    • PUT
    • PATCH
    • DELETE
  • Querying
    • Filtering
    • Sorting
    • Field Selection
      • Field Aliasing
      • Field Parameters
      • Embedding
    • Pagination
    • Skipping
  • Authentication & Authorization
  • Conditional Requests
  • Data Integrity & Concurrency Control
  • Data Validation
    • Nullable Values
    • Extensible Data Validation
  • Timeout and Request Cancellation
  • Logging
  • CORS
  • JSONP
  • Data Storage Handler
  • Custom Response Formatter / Sender
  • GraphQL
  • Hystrix
  • JSONSchema

Breaking Changes

Until we reach a stable v1, there will be occasional breaking changes to the rest-layer APIs. Breaking changes will however not arrive at patch releases.

Breaking changes since v0.2.0

No breaking changes since v0.2.0.

Breaking changes prior to v0.2.0

Below is an incomplete list of breaking changes included in v0.2.0:

  • PR #151: ValuesValidator FieldValidator attribute in schema.Dict struct replaced by Values Field.
  • PR #179: ValuesValidator FieldValidator attribute in schema.Array struct replaced by Values Field.
  • PR #204:
    • Storage drivers need to accept pointer to Expression implementer in query.Predicate.
    • filter parameters in sub-query will be validated for type match.
    • filter parameters will be validated for type match only, instead of type & constrains.
  • PR #228: Reference projection fields will be validated against referenced resource schema.
  • PR #230: Connection projection fields will be validated against connected resource schema.
  • PR #241: Always call OnUpdate field hook on HTTP PUT for existing documents. Deleting a field with Default value set, will always be reset to its default value.

Features

  • Automatic handling of REST resource operations
  • Full test coverage
  • Plays well with other net/http middleware
  • Pluggable resources storage
  • Pluggable response sender
  • GraphQL query support
  • GraphQL mutation support
  • Swagger Documentation
  • JSONSchema Output (partial)
  • Testing framework
  • Sub resources
  • Cascading deletes on sub resources
  • Filtering
  • Sorting
  • Pagination
  • Aliasing
  • Custom business logic
  • Event hooks
  • Field hooks
  • Extensible data validation and transformation
  • Conditional requests (Last-Modified / Etag)
  • Data integrity and concurrency control (If-Match)
  • Timeout and request cancellation through context
  • Logging
  • Multi-GET
  • Bulk inserts
  • Default and nullable values
  • Per resource cache control
  • Customizable authentication / authorization
  • Projections
  • Embedded resource serialization
  • Sub-request concurrency control
  • Custom ID field
  • Data versioning
  • Per resource circuit breaker using Hystrix
  • JSON-Patch support

Extensions

As REST Layer is a simple net/http handler. You can use standard middleware to extend its functionalities:

  • CORS
  • Method Override
  • Gzip, Deflate
  • JSONP
  • X-Forwarded-For
  • Rate Limiting
  • Operations Log
  • Hystrix storage handler wrapper

Main Storage Handlers

  • Memory (test only)
  • MongoDB

Alternate Storage Handlers

  • ElasticSearch (no longer actively tested)
  • SQL (third party)
  • Google Datastore (third party)
  • Kubernetes ConfigMap (third party)

Usage

…

Just run this code (or use the provided examples/demo):

$ go run examples/demo/main.go
2015/07/27 20:54:55 Serving API on http://localhost:8080

Using HTTPie, you can now play with your API.

First create a user:

$ http POST :8080/api/users name="John Doe"
HTTP/1.1 201 Created
Content-Length: 155
Content-Location: /api/users/ar6ejgmkj5lfl98r67p0
Content-Type: application/json
Date: Mon, 27 Jul 2015 19:10:20 GMT
Etag: "1e18e148e1ff3ecdaae5ec03ac74e0e4"
Last-Modified: Mon, 27 Jul 2015 19:10:20 GMT
Vary: Origin

{
    "id": "ar6ejgmkj5lfl98r67p0",
    "created": "2015-07-27T21:10:20.671003126+02:00",
    "updated": "2015-07-27T21:10:20.671003989+02:00",
    "name": "John Doe",
}

As you can see, the id, created and updated fields have been automatically generated by our OnInit field hooks.

Also notice the Etag and Last-Modified headers. Those guys allow data integrity and concurrency control down to the storage layer through the use of the If-Match and If-Unmodified-Since headers. They can also serve for conditional requests using If-None-Match and If-Modified-Since headers.

Here is an example of conditional request:

$ http :8080/api/users/ar6ejgmkj5lfl98r67p0 \
  If-Modified-Since:"Mon, 27 Jul 2015 19:10:20 GMT"
HTTP/1.1 304 Not Modified
Date: Mon, 27 Jul 2015 19:17:11 GMT
Vary: Origin

And here is a data integrity request following the RFC-5789 recommendations:

$ http PATCH :8080/api/users/ar6ejgmkj5lfl98r67p0 \
  name="Someone Else" If-Match:invalid-etag
HTTP/1.1 412 Precondition Failed
Content-Length: 58
Content-Type: application/json
Date: Mon, 27 Jul 2015 19:33:27 GMT
Vary: Origin

{
    "code": 412,
    "fields": null,
    "message": "Precondition Failed"
}

Retry with the valid etag:

$ http PATCH :8080/api/users/ar6ejgmkj5lfl98r67p0 \
  name="Someone Else" If-Match:'"1e18e148e1ff3ecdaae5ec03ac74e0e4"'

HTTP/1.1 200 OK
Content-Length: 159
Content-Type: application/json
Date: Mon, 27 Jul 2015 19:36:19 GMT
Etag: "7bb7a71b0f66197aa07c4c8fc9564616"
Last-Modified: Mon, 27 Jul 2015 19:36:19 GMT
Vary: Origin

{
    "created": "2015-07-27T21:33:09.168492448+02:00",
    "id": "ar6ejmukj5lflde9q8bg",
    "name": "Someone Else",
    "updated": "2015-07-27T21:36:19.904545093+02:00"
}

Note that even if you don't use conditional request, the Etag is always used by the storage handler to manage concurrency control between requests.

Another cool thing is sub-resources. We've set our posts resource as a child of the users resource. This way we can handle ownership very easily as routes are constructed as /users/:user_id/posts.

Lets create a post:

$ http POST :8080/api/users/ar6ejgmkj5lfl98r67p0/posts \
  title="My first post"
HTTP/1.1 200 OK
Content-Length: 212
Content-Type: application/json
Date: Mon, 27 Jul 2015 19:46:55 GMT
Etag: "307ae92df6c3dd54847bfc7d72422e07"
Last-Modified: Mon, 27 Jul 2015 19:46:55 GMT
Vary: Origin

{
    "id": "ar6ejs6kj5lflgc28es0",
    "created": "2015-07-27T21:46:55.355857401+02:00",
    "updated": "2015-07-27T21:46:55.355857989+02:00",
    "title": "My first post",
    "user": "ar6ejgmkj5lfl98r67p0"
}

Notice how the user field has been set with the user id provided in the route, that's pretty cool, huh?

We defined that we can cr

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Goapiapi-documentationapi-serverframework

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category后端框架
PricingOpen source

> Related tools

N
Node.js
基于 V8 的 JavaScript 运行时
D
Django
Python 高级 Web 框架
S
Spring Boot
Java 生态主流微服务框架