Welcome to the EchoServer
EchoServer is a web service which provides creating and managing mock apis with desired details.
I consider you already installed ruby
, rails
, postgres
in your system
first run:
$ sudo chmod +x bin/setup.sh
then:
$ bin/setup.sh app
setup.sh
will automatically set env var for database credentials, if you face error in console or running $ rspec
:
Please set your postgres database config in the .env
file in the root directory if you have any database connection problem. (also its possible to set variables in your shell env)
DATABASE_HOST=<your db host>
DATABASE_PORT=<your db port>
DATABASE_USERNAME=<your db username>
DATABASE_PASSWORD=<your db password>
Note. if your config is ok and you face peer connection error, check your postgres configuration
Please use this data to login, app does not support registration process
{
"password" : 'adminadmin',
"email" : "[email protected]"
}
system handles environments variables with .dotenv library and we set env variables in .env file in root directory, so all variables is accesable through ENV.
Note. this is for development purposes
Api list is available in the Postman, to use please click EchoServer please set url variable in postman to your remote url
in case of using online collection:
- Please select DEV environment
- token variable automatically will set after login
{{url}} : you need to set url to your local url or ngrok remote url if you use online collection
{{token}} : user token to work with token endpoints
{{id}} : created endpoint ID
if you want to run postman locally and test apis in local skip this section
Step 1
In ubuntu:
$ sudo snap install ngrok
In mac:
$ brew install ngrok/ngrok/ngrok
if you need more data about ngrok visit ngrok docs
step 2
you need to add your ngrok key to ngrok.yml file, use mine
ngrok config add-authtoken 1n0mFSVOTlDkEVPfZLOK75BY9TR_3APBxDQcaNwi1RYHkHd5k
step 3
port: for rails default its 3000
ngrok http <port>
step 4
Note. Use -b -p in running rails server
then add your ngrok host to your application.rb
config.hosts << "<your random ngrok host>.ngrok.io"
Note. at the moment no extra attributes accepted from input, all data is restricted to specified data, you can add data only to headers and body keys
Api documentation is hosted, please visit EchoServer API doc to see list of APIs.
using this command you can run application tests
$ rspec
ApplicationController: we use this controller to rescue and format all our exception accures in our application, this include rails application errors and custom error EchoError
.
under app/controllers/api/v1
our controllers file exists
EndpointsController: we use this controller to create our mocks and save them in our postgres database.
AuthenticationsController: this controller provide login feature for users.
BaseController: we use our base controller to apply controller wide functionality and for now it handles requests authorization
AuthToken: we keep our authentication information jwt for now in this table and intention of separating is for safe logout after user jwt expired
User: this entity is for keeping our user data
endpoints: endpoint entity keep our mock data, response column is json and we created it for query purposes, so we keep mock headers and body in jsonb(raw data)
so all spaces and duplicate key is possible to these columns
Intention of creating service layer is clean up controller from business logic and model from some action specific validation. each service attempted to be SRP and decoupled from other layers.
ChopData: this service in responsible for chop data primary keys as data
, attributes
, response
. we use it in create and update service
validate: this service is validating input data, at the moment extra data only accepts inside of headers and body key, other keys is only whitelisted to specified ones, we use it in create and update service.
Create: this service is for creating our mock apis based on defined constraint in validate service.
Update: this service is for updating our mock apis based on defined constraint in validate service.
Mock: this service is for serve our created mocks and if saved data was valid json it return, if not raw data returned.
SignIn: this service handles login logic.
serialization of application is handling by serializer
under serializer folder, used library is active model serializer
it uses json api v1 specifications to format output json
Note there is some alternative handles serialization in a fast way, the reason behind using active_model_serializer
is, its fully integrated
with rails and support serialization in OO way
app uses Authenticable::JWT
to handle jwt encode and decode process and it exist under controllers/concerns
folder
EchoError: our custom error and message format in implemented in this module
routing Tests are exists in under the spec/routing
folder
its under spec/requests
directory and intended to test integration of functionality, some of mock apis test is exists there
its under spec/controllers/api/v1/
directory and it tests different aspects of functionality and input/output of api
under spec/models
directory our entities tests are exists
we add jsonb to save raw data, its able to save duplicate keys its for rendering also we add response json its combination of a headers and body and its for query purposes.
yes user save duplicate data but its trade-off for searching performance.
response column is reserved for searching purposes, we are not gonna show it.
test coverage exists under coverage directory its for development purposes so we put it in .gitignore
file, to see result run $ rspec
then run below command to open in your desired browser
in Mac
$ open coverage/index.html
in Ubuntu
$ xdg-open coverage/index.html
you can just simply open index.html in your browser
Login
POST /login HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
{
"email": "[email protected]",
"password": "adminpass"
}
HTTP/1.1 201 Created
Location: http://example.com/greeting
Content-Type: application/vnd.api+json
{
"data": {
"id": "2",
"type": "users",
"attributes": {
"username": "admin",
"email": "[email protected]",
"authentication": {
"jwt": "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoyLCJpYXQiOjE2NjY3MDAyNDIsImV4cCI6MTY2Njc4NjY0MiwiaXNzIjoidXNlciIsInN1YiI6ImVjaG9fdXNlciIsImF1ZCI6ImVjaG9fc3lzdGVtIn0.NFf9huTxxMh2dxlY1vpsWj7xPrrDHylQNjiKRZ1dCoM",
"exp": "2022-10-26T12:17:22.722Z"
}
}
}
}
Create a Mock
POST /api/v1/endpoints HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
{
"data": {
"type": "endpoints",
"attributes": {
"verb": "GET",
"path": "/greet",
"response": {
"code": 200,
"headers": {},
"body": "{ \"message\": \"Hello, everyone\" }"
}
}
}
}
HTTP/1.1 201 Created
Location: http://example.com/greeting
Content-Type: application/vnd.api+json
{
"data": {
"id": "2",
"type": "endpoints",
"attributes": {
"verb": "GET",
"path": "/greet",
"response": {
"code": "200",
"headers": {},
"body": "{ \"message\": \"Hello, everyone\" }"
}
}
}
}
Call Created mock in specified Http method
GET /greet HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
HTTP/1.1 201 Created
Location: http://example.com/greeting
Content-Type: application/vnd.api+json
{
"message": "Hello, everyone"
}
The Boy Scout Rule:
“Always leave the campground cleaner than you found it.”
if you have complicated presentation layer its possible to use decorator to clean up your models my suggest is draper library, its has nice integration with rails
errors need to be parameterize to avoid some rails and database errors to shown in response
also its possible to use json validator such json-schema for validate input structure, for this case its too much to use external lib for app
there is some option to running and writing tests faster such as shoulda matchers it wasn't necessary to add additional library to this app.
you can validate mock api parameters per method, for ex: get can not have body params, this need to understand specification of these http methods in detail, I saw in elastic search we can use get with body params.
CONNECT: connect is intended only for use in requests to a proxy, so I'm not gonna implement it OPTIONS: this is intended to communication options with server and respond server capabilities, its not or our case TRACE : is not applicable to our mock server
there is some idea for log all incoming request using custom middleware check out request logger if you are interested
also is case of user concern its possible to add middleware to filter specific aspect of request.
its good idea to log database some important transaction, its good for trace some user trails