Code Monkey home page Code Monkey logo

smocker's Introduction

Smocker

CI Docker Repository Github Release Go Report Card License

Smocker (server mock) is a simple and efficient HTTP mock server.

The documentation is available on smocker.dev.

Table of contents

Installation

With Docker

docker run -d \
  --restart=always \
  -p 8080:8080 \
  -p 8081:8081 \
  --name smocker \
  ghcr.io/smocker-dev/smocker

Manual Deployment

# This will be the deployment folder for the Smocker instance
mkdir -p /opt/smocker && cd /opt/smocker
wget -P /tmp https://github.com/smocker-dev/smocker/releases/latest/download/smocker.tar.gz
tar xf /tmp/smocker.tar.gz
nohup ./smocker -mock-server-listen-port=8080 -config-listen-port=8081 &

Healthcheck

curl localhost:8081/version

User Interface

Smocker exposes a configuration user interface. You can access it in your web browser on http://localhost:8081/.

History

Mocks

Usage

Smocker exposes two ports:

  • 8080 is the mock server port. It will expose the routes you register through the configuration port
  • 8081 is the configuration port. It's the port you will use to register new mocks. This port also exposes a user interface.

Hello, World!

To register a mock, you can use the YAML and the JSON formats. A basic mock might look like this:

# helloworld.yml
# This mock register two routes: GET /hello/world and GET /foo/bar
- request:
    # Note: the method could be omitted because GET is the default
    method: GET
    path: /hello/world
  response:
    # Note: the status could be omitted because 200 is the default
    status: 200
    headers:
      Content-Type: application/json
    body: >
      {
        "hello": "Hello, World!"
      }

- request:
    method: GET
    path: /foo/bar
  response:
    status: 204

You can then register it to the configuration server with the following command:

curl -XPOST \
  --header "Content-Type: application/x-yaml" \
  --data-binary "@helloworld.yml" \
  localhost:8081/mocks

After your mock is registered, you can query the mock server on the specified route, so that it returns the expected response to you:

$ curl -i localhost:8080/hello/world
HTTP/1.1 200 OK
Content-Type: application/json
Date: Thu, 05 Sep 2019 15:49:32 GMT
Content-Length: 31

{
  "hello": "Hello, World!"
}

To cleanup the mock server without restarting it, you can execute the following command:

curl -XPOST localhost:8081/reset

For more advanced usage, please read the project's documentation.

Development

Backend

The backend is written in Go. You can use the following commands to manage the development lifecycle:

  • make start: start the backend in development mode, with live reload
  • make build, make VERSION=xxx build: compile the code and generate a binary
  • make lint: run static analysis on the code
  • make format: automatically format the backend code
  • make test: execute unit tests
  • make test-integration: execute integration tests

Frontend

The frontend is written with TypeScript and React. You can use the following commands to manage the development lifecycle:

  • yarn install: install the dependencies
  • yarn start: start the frontend in development mode, with live reload
  • yarn build: generate the transpiled and minified files and assets
  • yarn lint: run static analysis on the code
  • yarn format: automatically format the frontend code
  • yarn test: execute unit tests
  • yarn test:watch: execute unit tests, with live reload

Docker

The application can be packaged as a standalone Docker image. You can use the following commands to manage the development lifecycle:

  • make build-docker, make VERSION=xxx build-docker: build the application as a Docker image
  • make start-docker, make VERSION=xxx start-docker: run a Smocker Docker image

Caddy

If you need to test Smocker with a base path, you can use the Caddyfile provided in the repository (Caddy v2):

  • make start-release, make VERSION=xxx start-release: create a released version of Smocker and launch it with /smocker/ as base path
  • make start-caddy: start Caddy to make Smocker accessible at http://localhost:8082/smocker/

HTTPS

If you need to test Smocker with HTTPS enabled, the easiest way is to generate a locally signed certificate with mkcert:

# Install the local certificate authority
mkcert -install

# Create a certificate for localhost
mkcert -cert-file /tmp/cert.pem -key-file /tmp/key.pem localhost

Then, start Smocker with TLS enabled, using your generated certificate:

./smocker -mock-server-listen-port=44300 -config-listen-port=44301 -tls-enable -tls-cert-file=/tmp/cert.pem -tls-private-key-file=/tmp/key.pem

Authors

Contributors

smocker's People

Contributors

0xflotus avatar breneckd avatar dependabot[bot] avatar gwleclerc avatar kiliandeca avatar lukyer avatar mandyellow avatar marema31 avatar nilium avatar pierrechevallereau avatar pplr avatar rmcruzv avatar thiht avatar vaxvms avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

smocker's Issues

Starting Smocker with a persistence-directory doesn't work if the directory doesn't exist/is empty

/Users/thiht/workspace/go/bin/reflex --start-service \
		--decoration='none' \
		--regex='\.go$' \
		--inverse-regex='^vendor|node_modules|.cache/' \
		-- go run -ldflags="-X main.appName=smocker -X main.buildVersion=snapshot -X main.buildCommit=1fdcb52b32d9c00763fe2b106e924527e1e97c3d -X main.buildDate=2020-07-18T17:21:43+0200" main.go --log-level=debug --static-files ./build --persistence-directory ./sessions
Starting service
INFO[2020-07-18T17:21:49+02:00] Setting log level                             log-level=debug
ERRO[2020-07-18T17:21:49+02:00] Unable to load sessions: stat ./sessions: no such file or directory

the folder and the files should be created automatically if they don't exist

Logo

This one is cool, and under CC BY License Smocker

Ugly button

Capture d’écran 2020-06-30 à 12 12 31

The Reset button text is not centered, the padding is too narrow on the right.

Setting the following makes it better:

.ant-btn>.anticon+span,
.ant-btn>span+.anticon {
    margin-left: initial;
}

but it makes the Add mocks and Visualize buttons uglier :/

Create a mock from a request

A nice to have workflow would be the following:

  • On a request in the history, click on a "+" (title: "Create mock from request")
  • The mock editor opens, prefilled with:
- request:
    method:        # The request method
    path:          # The request path
    query_params:  # The request query params
    headers:       # The request headers (the user can remove the unnecessary ones as needed, but maybe we can filter some of them)
    # no body
- response:
    status: 200
    headers:
      Content-Type: application/json
    body: >

Add status filters

The most useful filter would be "Show Smocker errors", that would filter on response codes >= 600

Mock generator generates invalid body matcher

When creating a new mock from entry an entry with a JSON body on the UI, something like this is generated:

- request:
    path: ...
    method: ...
    body:
      a:
        b: 3

instead of:

- request:
    path: ...
    method: ...
    body:
      a.b: 3

We should generate something following objx format, or not generate anything at all for the body

Improve matcher display on UI

This is not explicit:

Matcher display on mocks view

In this case, we should write something like "Method ShouldMatch ." and "Path ShouldMatch ." or something like that.

Implements the real world example

It could be great to have a full working real world example:

  • two web services
  • a compose file to run them as production
  • a compose file which use Smocker to mock one of them
  • venom tests

Display 666 errors more clearly

When we have a 666 error code, we know the body contains a Smocker error.
We could display a more beautiful error message on the UI in this case

Support HTTPS

Currently Smocker can work as a http proxy if you try to call an API using http_proxy variable. The call will be redirected to Smocker.

You can test this by:

  • starting Smocker:
make start
  • making a call using Smocker as http proxy
export http_proxy=http://localhost:8080/
curl -v http://jsonplaceholder.typicode.com/todos/1

Then you should see the call on Smocker.

But when we try to make a call using HTTPS and HTTPS_PROXY, the http client send a CONNECT request on the proxy server which is not handled correctly by Smocker.
It will respond to the call with a "No mock found matching the request" which will cancel the https request on client side.

Mocks should be synchronized

With this mock for example:

request:
  method: GET
  path: /foo
context:
  times: 3
response:
  status: 200

If a client runs 10 calls in parallel to /foo, there's a risk that the mock server replies more than 3 times

Add header on proxy requests

I propose to add a 'headers' property on proxy section to define headers to be injected in the request before sending to proxy destination.

For example:

proxy:
    host: https://example.com
    headers:
        X-Forwared-Proto: http

If ok, I can work on a pull request.

Improve sessions handling

Session names should be unique, and sessions created with POST /sessions?name=xxx should overwrite the previous session with the same name.

Maybe the POST /sessions?name=xxx should be replaced with a PUT /sessions?name=xxx

Simplify header/query_param matching with custom matcher

The following syntaxes are supported:

headers:
  X-Example-Header: test
headers:
  # multiple occurrences
  X-Example-Header: [test, test2, test3]
headers:
  X-Example-Header:
    # array is required even for a single matcher
    - matcher: ShouldMatch
      value: test.*

The following should be allowed as well:

headers:
  X-Example-Header: 
    # no array
    matcher: ShouldMatch
    value: test.*

Optimize display of huge payloads

Maybe don't load huge payloads on the DOM directly but ask confirmation to the user.

Example: button "This payload is huge. Click to display it"

Add "New mock from request" on proxied responses

With the following workflow:

  • Create a proxy mock
  • Make a request matching the proxy mock
  • Smocker makes the call to the host and returns the response

If the response is not what I want for my test, I would like to be able to easily create a mock from the UI even if the call was successful to override a specific proxy response

Webhook-style calls

It's very common for services to callback some URI after some was processed — read: webhook call. This may happens after a certain period of time.

It would be nice if Smocker will be able to make those webhook calls after a given mock definition is executed. For instance, to simulate that a service received the HTTP call and based on the input it will respond back to /path/to/webhook with response within x seconds.

Not sure if this is doable with proxies.

Allow to refer to files in mock definitions

I'm working with ancient APIs these days. The responses are JSON or XML files around 3,000 (even more) lines length.

I would like to use Smocker at the new work place, but so far I haven't found a way to do something like this with Smocker:

- request:
    method: GET
    path: /hello/world
  response:
    headers:
      Content-Type: application/json
    body: file:/path/to/hello_world_response.json

I'm aware this not even valid YAML, but the file:/path/to/hello_world_response.json is just an example of what I'm trying to do, which is only to refer to a file with the content of the body, instead of putting the gigantic response there. If that's impossible to do these days, it would be nice to have a declarative way to implement such things in the YAML configuration file — probably with a fixed location for these kind of files.

Moreover, those are usually templates, because there is always something that needs to be changed before sending them back to the user-agents.

Can't read session name too long

Capture d’écran 2020-06-04 à 14 56 36

If the session name is too long, we can't read it. We should:

  • add a title attribute with the full name
  • display the current session name as a header on the mocks and history page
  • maybe add it to the document <title> too

Add an option to be able to set a max retention of history

It could be great to be able to set the maximum number of messages we want to store by session

Why:
Using that we could be able to use smocker as à dev gateway without worrying that memory increases as calls are made.

How:
On each call we can compare the history size to the retention and remove the oldest one when len(history) > retention

Add possibility to accept self signed certificates or ignore cert errors on proxy

Hi,

I'm currently trying to use smocker with a proxy mock which access https. The problem is now, that I get

Error during request redirection: Get "https://....": x509: certificate is valid for ... not ...."

or if using the IP:

Error during request redirection: Get "https://....": x509: certificate signed by unknown authority

back.

Is it possible to tell smocker to ignore certificate errors?

Proxy: don't follow redirection

When the response of a 'proxy' mock is a redirection, for example an HTTP 302, smocker follow the redirection instead of forwarding the response back. This is not expected for a reverse proxy.

Reduce js files size

Currently, the bundled js file is too big (1.24 MB)

It would be great to try to reduce it (maybe by using tree shaking or parcel plugins)

Extended body matching

Right now, the request body is a basic StringMatcher. This limits a lot how we can manipulate it.
At the minimum, it would be nice to be able to perform rich matching on a JSON body field.

For example, if we want to match a body containing a foobar key with the value "Hello, World", for instance:

{
  "foobar": "Hello, World"
}

the best we can do right now is something like:

request:
  body:
    matcher: ShouldMatch
    value: '"foobar":\s*"Hello, World!"'

A better way to do it would be to apply matchers on the individual body field, by parsing it as JSON, for example:

request:
  body:
    foobar: Hello, World

This allows us to apply powerful matching strategies, such as:

request:
  body:
    foobar:
      matcher: ShouldMatch
      value: Hello, (.+)

For nested fields, the syntax could use stretch/objx (. for nested keys, [n] for arrays). Examples:

request:
  body:
    my_array[2]: foo
    parent_key.child_key: bar

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.