https://github.com/nomemory/serverneat
A Kotlin DSL for creating mock servers - using MockNeat for generating data
https://github.com/nomemory/serverneat
Last synced: over 1 year ago
JSON representation
A Kotlin DSL for creating mock servers - using MockNeat for generating data
- Host: GitHub
- URL: https://github.com/nomemory/serverneat
- Owner: nomemory
- License: apache-2.0
- Created: 2020-04-14T20:38:08.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2021-07-21T03:38:28.000Z (about 5 years ago)
- Last Synced: 2025-03-22T06:31:48.469Z (over 1 year ago)
- Language: Kotlin
- Homepage:
- Size: 83 KB
- Stars: 21
- Watchers: 1
- Forks: 1
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ServerNeat
## Introduction
*ServerNeat* is (~not another~) a Kotlin Web Server for mocking and stubbing Rest APIs.
It provides and easy to use DSL and seamless integration with [MockNeat](http://www.mockneat.com) for generating dynamic json responses.
*ServerNeat* can be used as standalone application, capable of loading, compiling and evaluating `kts` scripts, or as a Kotlin/Java library.
## Building the stand-alone mock server
By executing the `application` task, a a (fat) stand-alone jar is created in the `build\libs` folder:
Gradle:
```groovy
gradle application
```
Running the server:
```
java -jar serverneat-all-1.0-SNAPSHOT.jar -f
```
Note: in the `examples\` folder there are a few `.kts` scripts that can be used for testing.
## Features
The server supports the following types of responses:
| ResponseType | Description |
| ------------ | ----------- |
| PlainText | Responds to the HTTP by returning simple `String` values as the response body. |
| File Content | Responds to the request reading the content of a file and returning it as `String`. It can be useful when you want to separate the response bodies from the configuration. |
| Resource Content | Similar to `File Content`, except the files are read as Resources from the `resources` folder. It's particularly useful when you don't run **serverneat** as standalone application but you use it as a "library". |
| File Download | Useful when you want to emulate a route that is allowing the user to download a file. |
| JSON Content | Allows you to generate JSON in an instant using a nice DSL and www.mockneat.com integration. |
## Examples
Check the `examples` folder.
### Plain text response - Hello world
```kotlin
import net.andreinc.serverneat.server.server
server {
httpOptions {
host = "localhost"
port = 8081
}
globalHeaders {
header("Content-Type", "application/text")
}
routes {
get {
path = "/plainText"
response {
header("plain", "text")
statusCode = 200
plainText {
value = "Hello World!"
}
}
}
}
}.start()
```
### Json Response (Simple)
```kotlin
import net.andreinc.serverneat.mockneat.extension.obj
import net.andreinc.serverneat.server.server
server {
httpOptions {
host = "localhost"
port = 8081
}
globalHeaders {
header("Content-Type", "application/json")
}
routes {
get {
path = "/user/100"
response {
header("plain", "text") // Adding a custom header to the response
statusCode = 200
json {
value = obj {
"firstName" const "Mike"
"lastName" const "Smith"
"someFiles" const arrayOf("file1.txt", "file2.txt")
"anotherObject" value obj {
"someData" const "someValue"
}
}
}
}
}
}
}.start()
```
PS: When creating an inner structure it's important to use `value` instead of `const`.
Calling the service `curl localhost:8081/user/100`:
```
{
"firstName": "Mike",
"lastName": "Smith",
"anotherObject": {
"someData": {}
},
"someFiles": [
"file1.txt",
"file2.txt"
]
}
```
PS: When creating an inner structure it's important to use `value` instead of `const`.
### Json Response (Dynamic - using [MockNeat](https://www.mockneat.com/))
The value object can be any [MockUnit](https://www.mockneat.com/tutorial/#everything-is-a-mockunitt).
```kotlin
import net.andreinc.mockneat.unit.address.Cities.cities
import net.andreinc.mockneat.unit.financial.CreditCards.creditCards
import net.andreinc.mockneat.unit.time.LocalDates.localDates
import net.andreinc.mockneat.unit.user.Genders.genders
import net.andreinc.mockneat.unit.user.Names.names
import net.andreinc.serverneat.mockneat.extension.obj
import net.andreinc.serverneat.server.server
server {
httpOptions {
host = "localhost"
port = 8081
}
globalHeaders {
header("Content-Type", "application/json")
}
routes {
get {
path = "/users"
response {
statusCode = 200
json {
persistent = true // generated data will be stored in the file "usersList.json"
file = "dyanmic-example/usersList.json"
value = obj {
"users" value obj {
"firstName" value names().first()
"lastName" value names().last()
"gender" value genders()
"financialInformation" value obj {
"creditCard1" value creditCards().visa()
"creditCard2" value creditCards().amex()
}
"visits" value obj {
"time" value localDates().thisYear()
"city" value cities().capitalsEurope()
}.list(5)
}.list(50)
}
}
}
}
}
}.start()
```
And the reponse will be
```json
{
"users": [
{
"firstName": "Tommie",
"lastName": "Pecinousky",
"visits": [
{
"city": "Copenhagen",
"time": {
"year": 2020,
"month": 1,
"day": 7
}
},
{
"city": "Monaco",
"time": {
"year": 2020,
"month": 11,
"day": 13
}
},
{
"city": "Tallinn",
"time": {
"year": 2020,
"month": 10,
"day": 22
}
},
{
"city": "Sarajevo",
"time": {
"year": 2020,
"month": 3,
"day": 7
}
},
{
"city": "Athens",
"time": {
"year": 2020,
"month": 12,
"day": 15
}
}
],
"financialInformation": {
"creditCard2": "340529111074115",
"creditCard1": "4647171048830798"
},
"gender": "Female"
},
{
"firstName": "Sid",
"lastName": "Falge",
"visits": [
{
"city": "Berlin",
"time": {
"year": 2020,
"month": 2,
"day": 22
}
},
{
"city": "Brussels",
"time": {
"year": 2020,
"month": 1,
"day": 27
}
},
{
"city": "Athens",
"time": {
"year": 2020,
"month": 12,
"day": 28
}
},
{
"city": "San Marino",
"time": {
"year": 2020,
"month": 10,
"day": 23
}
},
{
"city": "Stockholm",
"time": {
"year": 2020,
"month": 5,
"day": 12
}
}
],
"financialInformation": {
"creditCard2": "373802757435803",
"creditCard1": "4332758675303071"
},
"gender": "Male"
}
/// and so on
]
}
```
*and son on for the rest of the users*