Giter Site home page Giter Site logo

rails-echo-server's Introduction

ECHO Server

This is an implementation of a configurable "Echo" server, where clients can define endpoints that respond according to their specification.

Requirements

The server is written in Ruby 3 and Ruby on Rails 6. You will also need the Ruby Bundler to build the server.

Setup

With ruby and bundle installed on your system you can build the application locally using

$ bundle install

You will then need to run initial database migrations to setup the application:

$ rails db:migrate

By default the application uses a local sqlite3 database.

Rails comes with a local development server. To run the application with it use

$ rails server

which starts the application and lets it listen on port 3000. Run rails server --help for additional configuration options of the local server.

You can also run the test suite with

$ bundle exec rspec

Usage

With the server running you can make HTTP requests to it in order to create echo endpoints and call them afterwards. For demonstration purposes I'll use httpie as a client.

Create a new endpoint

The echo server provides one resource endpoint /endpoints that allows you to list, show, create and update endpoints. The server handles JSON payloads in the json:api format. A typical payload for an endpoint definition might look like this:

{
  "data": {
    "type": "endpoints",
    "attributes": {
      "verb": "GET",
      "path": "/greeting",
      "response": {
        "code": 200,
        "headers": {
          "Cache-Control": "max-age=3600",
          "Last-Modified": "Thu, 27 May 2021 14:00:00 GMT"
        },
        "body": "\"{ \"message\": \"Hello, world\" }\""
      }
    }
  }
}

You can find the above definition in the greeting_endpoint.json. To use it and create an endpoint using httpie, run this command:

$ http POST localhost:3000/endpoints < greeting_endpoint.json

HTTP/1.1 201 Created
[...]
{
    "data": {
        "attributes": {
            "path": "/greeting",
            "response": {
                "body": "{ \"message\": \"Hello, world\" }",
                "code": 200,
                "headers": {
                    "Cache-Control": "max-age=3600",
                    "Last-Modified": "Thu, 27 May 2021 14:00:00 GMT"
                }
            },
            "verb": "GET"
        },
        "id": 1,
        "type": "endpoints"
    }
}

The response will give you the endpoint id which you can use to refer to this specific endpoint later.

Call your endpoint

After creation you can call your defined endpoint:

$ http localhost:3000/greeting

HTTP/1.1 200 OK
[...]
{
    "message": "Hello, world"
}

Endpoint Documentation

GET /endpoints

Returns a list of created endpoints.

GET /endpoints
Accept: application/vnd.api+json

200 OK
Content-Type: application/vnd.api+json
{
    "data": [
        {
            "attributes": {
                "path": "/greeting",
                "response": {
                    "body": "{ \"message\": \"Hello, world\" }",
                    "code": 200,
                    "headers": {
                        "Cache-Control": "max-age=3600",
                        "Last-Modified": "Thu, 27 May 2021 14:00:00 GMT"
                    }
                },
                "verb": "GET"
            },
            "id": 1,
            "type": "endpoints"
        }
    ]
}

POST /endpoints

Creates a new endpoint.

POST /endpoints
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
{
  "data": {
    "type": "endpoints",
    "attributes": {
      "verb": "GET",
      "path": "/greeting",
      "response": {
        "code": 200,
        "headers": {
          "Cache-Control": "max-age=3600",
          "Last-Modified": "Thu, 27 May 2021 14:00:00 GMT"
        },
        "body": "{ \"message\": \"Hello, world\" }"
      }
    }
  }
}

201 Created
Content-Type: application/vnd.api+json
{
    "data": {
        "attributes": {
            "path": "/greeting",
            "response": {
                "body": "{ \"message\": \"Hello, world\" }",
                "code": 200,
                "headers": {
                    "Cache-Control": "max-age=3600",
                    "Last-Modified": "Thu, 27 May 2021 14:00:00 GMT"
                }
            },
            "verb": "GET"
        },
        "id": 3,
        "type": "endpoints"
    }
}

PATCH /endpoints/:id

Updates the endpoint with the specified id

PATCH /endpoints/3
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
{
  "data": {
    "type": "endpoints",
    "attributes": {
      "verb": "GET",
      "path": "/greeting",
      "response": {
        "code": 200,
        "headers": {
          "Cache-Control": "max-age=3600",
          "Last-Modified": "Thu, 27 May 2021 14:00:00 GMT"
        },
        "body": "{ \"message\": \"Hello, world\" }"
      }
    }
  }
}

200 OK
Content-Type: application/vnd.api+json
{
    "data": {
        "attributes": {
            "path": "/greeting",
            "response": {
                "body": "{ \"message\": \"Hello, world\" }",
                "code": 200,
                "headers": {
                    "Cache-Control": "max-age=3600",
                    "Last-Modified": "Thu, 27 May 2021 14:00:00 GMT"
                }
            },
            "verb": "GET"
        },
        "id": 3,
        "type": "endpoints"
    }
}

DELETE /endpoints/:id

Deletes the endpoint with the specified id

DELETE /endpoints/1

204 No Content

Errors and Validation

The server implements some validation for endpoint input:

  • HTTP methods are only allowed to be one of 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'PATCH'
  • Paths are restricted to alphanumerical characters
  • Path and Method combinations for endpoints need to be unique

When validation fails or when endpoints can not be found, the server responds with an error message, for example:

GET /endpoints/10
Accept: application/vnd.api+json

404 Not Found
Content-Type: application/vnd.api+json
{
    "errors": [
        {
            "code": "not_found",
            "detail": "Couldn't find Endpoint with 'id'=10"
        }
    ]
}

Possible improvements

  • Default /endpoints routes might need to be protected from being overwritten. This should not be a problem because the route definition for them comes BEFORE the custom routes, but returning something like 409 Conflict for those routes would still be a good idea.
  • When accessing an existing endpoint path with a different HTTP method the server will respond with a 404 Not Found. Instead, it could respond with 405 Method Not Allowed and add the Allow response header with the method(s) currently supported
  • Error messages, especially for endpoint path/method combinations not found, can be improved. They currently return the ActiveRecord error message which indicates that the backend uses some SQL-like technology, which is not ideal from a security perspective.
  • json:api provides some good opportunities to work with paging and filtering, which could come in handy when creating lots of endpoint definitions.

rails-echo-server's People

Watchers

Mathias Lenz avatar

Forkers

pallavits

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.