Skip to content

Commit 0ebf81c

Browse files
authored
Merge pull request #876 from marle3003/develop
Develop
2 parents fcefd49 + ae59662 commit 0ebf81c

62 files changed

Lines changed: 2479 additions & 1821 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 91 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
</a>
55
</p>
66

7-
<h3 align="center">Your API Mocking Tool for Agile Development</h3>
7+
<h3 align="center">Mock APIs Across Protocols. Test Faster. Ship Better.</h3>
88

99
<p align="center">
1010
<a href="https://github.com/marle3003/mokapi/releases"><img src="https://img.shields.io/github/release/marle3003/mokapi.svg" alt="Github release"></a>
@@ -17,124 +17,133 @@
1717
<a href="https://mokapi.io/docs/welcome">Documentation</a>
1818
</p>
1919

20-
# 🚀 Overview
20+
## What is Mokapi?
2121

22-
Mokapi is an open-source tool that helps Agile, DevOps, and Continuous
23-
Deployment teams design, test, and validate APIs before implementation.
24-
It enables rapid prototyping of scenarios—like delayed responses,
25-
failures, or edge cases—without needing a live backend. By simulating
26-
real-world conditions early, Mokapi improves API quality and reduces
27-
the risk of bugs in production.
22+
Mokapi is an open-source API mocking tool that lets you develop and test without waiting
23+
for backends. Mock REST APIs, Kafka topics, LDAP directories, and SMTP servers using
24+
OpenAPI and AsyncAPI specifications.
2825

29-
# ✨ Features
26+
Perfect for:
27+
- Frontend developers building UIs before backends exist
28+
- QA teams testing edge cases, errors, and timeouts
29+
- DevOps engineers running reliable CI/CD tests without external dependencies
30+
- API designers prototyping and validating contracts early
3031

31-
- **Multiple Protocol support**: HTTP, HTTPS, Apache Kafka, SMTP, LDAP
32-
- **Everything as Code**: Reusing, version control, consistency and integrate mocks with your CI/CD.
33-
- **An embedded JavaScript engine** to control everything - status, headers, delays, errors or other edge cases.
34-
- **Patch Configuration** changes for mocking needs, rather than changing the original contract
35-
- **Multiple Provider support**: File, HTTP, GIT, NPM to gather configurations and scripts.
36-
- **Dashboard** to see what's going on.
32+
## Quick Start
3733

38-
## 🧩 OpenAPI & AsyncAPI Support
34+
Try Instantly
3935

40-
Mokapi supports mocking REST APIs using **OpenAPI 2.0 / 3.0 / 3.1** and event-driven systems using **AsyncAPI**.
41-
42-
## 🔧 Spin Up Mokapi
43-
44-
Install and start Mokapi using one of the following methods.
45-
Replace the URL with your own OpenAPI or AsyncAPI specification.
46-
47-
Windows
48-
```shell
49-
choco install mokapi
50-
mokapi https://petstore31.swagger.io/api/v31/openapi.json
5136
```
52-
53-
MacOS
54-
```shell
55-
brew tap marle3003/tap
56-
brew install mokapi
57-
mokapi https://petstore31.swagger.io/api/v31/openapi.json
37+
npx go-mokapi https://petstore3.swagger.io/api/v3/openapi.json
5838
```
5939

60-
Docker
61-
```shell
62-
docker run -p 80:80 -p 8080:8080 mokapi/mokapi:latest https://petstore31.swagger.io/api/v31/openapi.json
63-
```
40+
Then test your mock:
6441

65-
# 🎯 Hit Your First Mock
66-
Once Mokapi is running, you can make requests to your mocked API like so:
67-
```shell
68-
curl http://localhost/api/v31/pet/2 -H 'Accept: application/json'
6942
```
43+
curl http://localhost/api/v3/pet/1 -H 'Accept: application/json'
44+
```
45+
46+
## Key Features
7047

71-
# 🧩 Customize Your Mock with JavaScript
48+
### Multi-Protocol Support
49+
Mock HTTP/HTTPS, Apache Kafka, LDAP, and SMTP — all from a single tool.
7250

73-
Mokapi makes it simple to control responses using embedded JavaScript.
51+
### Specification-Driven
52+
Uses OpenAPI and AsyncAPI specs as the source of truth. Your mocks stay aligned with your API contracts.
7453

75-
For example, you can dynamically change the response based on query parameters:
54+
### Dynamic Behavior with JavaScript
7655

77-
```typescript
78-
import { on } from 'mokapi';
56+
Control responses, simulate errors, add delays, or create complex workflows using embedded JavaScript:
57+
```javascript
58+
import { on } from 'mokapi'
7959

8060
export default function() {
8161
on('http', (request, response) => {
82-
switch (request.path.petId) {
83-
case 2:
84-
response.data.name = 'Betty';
85-
case 9:
86-
response.statusCode = 404;
62+
// Return 404 for specific IDs
63+
if (request.path.petId === '999') {
64+
response.statusCode = 404
65+
return
8766
}
88-
});
67+
68+
// Customize response data
69+
response.data.name = 'Custom Pet Name'
70+
})
8971
}
9072
```
9173

92-
# 🖥️ Dashboard
74+
### Everything as Code
75+
Version control your mocks alongside your code. Run them in CI/CD pipelines. No UI configuration required.
9376

94-
Mokapi’s dashboard lets you visualize your mock APIs. View requests and responses in real-time, generate and validate sample data for testing.
77+
### Configuration Patching
78+
Override parts of your OpenAPI spec without modifying the original file. Perfect for testing different scenarios.
9579

96-
<img src="webui.png" alt="Mokapi Web UI" title="Mokapi Web UI" />
80+
### Built-in Dashboard
81+
Visualize requests, responses, and logs in real-time at http://localhost:8080
82+
<img src="https://raw.githubusercontent.com/marle3003/mokapi/refs/heads/main/webui.png" alt="Mokapi Web UI" title="Mokapi Web UI" />
9783

98-
# 🧪 Learn by Example
84+
### Multiple Providers
85+
Load specs from local files, HTTP URLs, Git repositories, or NPM packages.
9986

100-
Explore tutorials that walk you through mocking different protocols and scenarios:
87+
## Common Use Cases
10188

102-
- 🌍 [Get started with REST API](https://mokapi.io/resources/tutorials/get-started-with-rest-api)\
103-
This tutorial will show you how to mock a REST API using an OpenAPI specification.
89+
### Frontend Development
90+
Mock backend APIs while building UIs. Test loading states, errors, and edge cases without waiting for real endpoints.
10491

105-
-[Mocking Kafka with AsyncAPI](https://mokapi.io/resources/tutorials/get-started-with-kafka)\
106-
Mocking a Kafka topic using Mokapi and verifying that a producer generates valid messages.
92+
### API Testing
93+
Simulate timeouts, 500 errors, rate limits, and malformed responses. Test how your application handles failures.
10794

108-
- 👨‍💻 [Mocking LDAP Authentication](https://mokapi.io/resources/tutorials/mock-ldap-authentication-in-node)\
109-
Simulate LDAP-based login flows, including group-based permissions.
95+
### CI/CD Integration
96+
Run fast, reliable tests without external dependencies. No flaky tests due to network issues or unavailable services.
11097

111-
- 📧 [Mocking SMTP Mail Servers](https://mokapi.io/resources/tutorials/mock-smtp-server-send-mail-using-node)\
112-
Use Mokapi to simulate sending and receiving emails in Node.js apps.
98+
### Contract Validation
99+
Validate that your requests and responses match your OpenAPI specification. Catch breaking changes early.
113100

114-
- 🖥️ [End-to-End Testing with Jest and GitHub Actions](https://mokapi.io/resources/tutorials/running-mokapi-in-a-ci-cd-pipeline)\
115-
Integrate Mokapi into your CI pipeline for full-stack E2E testing.
101+
# Example Tutorials
116102

117-
> More examples are available on [mokapi.io/resources](https://mokapi.io/resources)
103+
Explore tutorials that walk you through mocking different protocols and scenarios:
104+
105+
- [Get started with REST API](https://mokapi.io/resources/tutorials/get-started-with-rest-api)
106+
Mock a REST API using OpenAPI specification
107+
108+
- [Mock Kafka with AsyncAPI](https://mokapi.io/resources/tutorials/get-started-with-kafka)
109+
Simulate Kafka topics and validate message producers
110+
111+
- [Mock LDAP Authentication](https://mokapi.io/resources/tutorials/mock-ldap-authentication-in-node)\
112+
Test authentication flows without a real LDAP server
118113

119-
# 📚 Documentation
114+
- [Mock SMTP Mail Servers](https://mokapi.io/resources/tutorials/mock-smtp-server-send-mail-using-node)\
115+
Test email workflows without sending real messages
120116

121-
- [Get Started](https://mokapi.io/docs/welcome)
122-
- [HTTP](https://mokapi.io/docs/http/overview)
123-
- [Kafka](https://mokapi.io/docs/kafka/overview)
124-
- [LDAP](https://mokapi.io/docs/ldap/overview)
125-
- [SMTP](https://mokapi.io/docs/mail/overview)
126-
- [Javascript API](https://mokapi.io/docs/javascript-api/overview)
127-
- [Resources](https://mokapi.io/resources)
117+
- [CI/CD Integration with GitHub Actions](https://mokapi.io/resources/tutorials/running-mokapi-in-a-ci-cd-pipeline)\
118+
Run Mokapi in automated test pipelines
128119

129-
# ☕ Support
120+
> More examples [mokapi.io/resources](https://mokapi.io/resources)
130121
131-
Show your love for Mokapi and support the project by grabbing some cool merch!
132-
[Visit the Mokapi Merchandise Store](https://mokapi.myspreadshop.ch) 🔥
122+
## Documentation
133123

134-
If you like Mokapi, consider buying me a coffee:
124+
- [Getting Started Guide](https://mokapi.io/docs/welcome)
125+
- [HTTP/REST API Documentation](https://mokapi.io/docs/http/overview)
126+
- [Kafka Documentation](https://mokapi.io/docs/kafka/overview)
127+
- [LDAP Documentation](https://mokapi.io/docs/ldap/overview)
128+
- [SMTP/Mail Documentation](https://mokapi.io/docs/mail/overview)
129+
- [JavaScript API Reference](https://mokapi.io/docs/javascript-api/overview)
130+
- [Configuration Guide](https://mokapi.io/docs/configuration/overview)
131+
132+
## Support the Project
133+
134+
If Mokapi helps your team ship faster, consider supporting development:
135135

136136
<a href="https://www.buymeacoffee.com/mokapi" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>
137137

138-
# 📄 License
138+
## License
139+
140+
MIT License - see [LICENSE](https://github.com/marle3003/mokapi/blob/main/LICENSE) for details.
141+
142+
## Links
139143

140-
This project is licensed under the MIT License. See the [LICENSE](https://github.com/marle3003/mokapi/blob/main/LICENSE) file for details.
144+
- Website: [mokapi.io](https://mokapi.io)
145+
- GitHub: [github.com/marle3003/mokapi](https://github.com/marle3003/mokapi)
146+
- NPM Package: [npmjs.com/package/go-mokapi](https://npmjs.com/package/go-mokapi)
147+
- Documentation: [mokapi.io/docs](https://mokapi.io/docs)
148+
- Tutorials: [mokapi.io/resources/tutorials](https://mokapi.io/resources/tutorials)
149+
- Blog: [mokapi.io/resources/blogs](https://mokapi.io/resources/blogs)

api/handler_fileserver_test.go

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package api_test
22

33
import (
44
"fmt"
5-
"github.com/stretchr/testify/require"
65
"mokapi/api"
76
"mokapi/config/dynamic"
87
"mokapi/config/static"
@@ -14,6 +13,8 @@ import (
1413
"net/url"
1514
"strings"
1615
"testing"
16+
17+
"github.com/stretchr/testify/require"
1718
)
1819

1920
func TestHandler_FileServer(t *testing.T) {
@@ -168,7 +169,7 @@ func TestOpenGraphInDashboard(t *testing.T) {
168169
app := runtime.New(cfg)
169170
app.AddHttp(&dynamic.Config{Info: dynamic.ConfigInfo{Url: mustParse("https://foo.bar")}, Data: openapitest.NewConfig("3.0",
170171
openapitest.WithInfo("Swagger Petstore", "1.0", "This is a sample server Petstore server."),
171-
openapitest.WithPath("/pet/{petId}", openapitest.NewPath()),
172+
openapitest.WithPath("/pet/{petId}"),
172173
)},
173174
)
174175
h := api.New(app, static.Api{Path: "/mokapi", Dashboard: true})
@@ -192,9 +193,9 @@ func TestOpenGraphInDashboard(t *testing.T) {
192193
app := runtime.New(cfg)
193194
app.AddHttp(&dynamic.Config{Info: dynamic.ConfigInfo{Url: mustParse("https://foo.bar")}, Data: openapitest.NewConfig("3.0",
194195
openapitest.WithInfo("Swagger Petstore", "1.0", "This is a sample server Petstore server."),
195-
openapitest.WithPath("/pet/{petId}", openapitest.NewPath(
196+
openapitest.WithPath("/pet/{petId}",
196197
openapitest.WithPathInfo("foo", "bar"),
197-
)),
198+
),
198199
),
199200
})
200201
h := api.New(app, static.Api{Path: "/mokapi", Dashboard: true})
@@ -218,9 +219,9 @@ func TestOpenGraphInDashboard(t *testing.T) {
218219
app := runtime.New(cfg)
219220
app.AddHttp(&dynamic.Config{Info: dynamic.ConfigInfo{Url: mustParse("https://foo.bar")}, Data: openapitest.NewConfig("3.0",
220221
openapitest.WithInfo("Swagger Petstore", "1.0", "This is a sample server Petstore server."),
221-
openapitest.WithPath("/pet/{petId}", openapitest.NewPath(
222+
openapitest.WithPath("/pet/{petId}",
222223
openapitest.WithPathInfo("", "bar"),
223-
))),
224+
)),
224225
})
225226
h := api.New(app, static.Api{Path: "/mokapi", Dashboard: true})
226227
try.Handler(t,
@@ -243,9 +244,9 @@ func TestOpenGraphInDashboard(t *testing.T) {
243244
app := runtime.New(cfg)
244245
app.AddHttp(&dynamic.Config{Info: dynamic.ConfigInfo{Url: mustParse("https://foo.bar")}, Data: openapitest.NewConfig("3.0",
245246
openapitest.WithInfo("Swagger Petstore", "1.0", "This is a sample server Petstore server."),
246-
openapitest.WithPath("/pet/{petId}", openapitest.NewPath(
247-
openapitest.WithOperation("GET", openapitest.NewOperation()),
248-
))),
247+
openapitest.WithPath("/pet/{petId}",
248+
openapitest.WithOperation("GET"),
249+
)),
249250
})
250251
h := api.New(app, static.Api{Path: "/mokapi", Dashboard: true})
251252
try.Handler(t,
@@ -268,12 +269,13 @@ func TestOpenGraphInDashboard(t *testing.T) {
268269
app := runtime.New(cfg)
269270
app.AddHttp(&dynamic.Config{Info: dynamic.ConfigInfo{Url: mustParse("https://foo.bar")}, Data: openapitest.NewConfig("3.0",
270271
openapitest.WithInfo("Swagger Petstore", "1.0", "This is a sample server Petstore server."),
271-
openapitest.WithPath("/pet/{petId}", openapitest.NewPath(
272-
openapitest.WithOperation("GET", openapitest.NewOperation()),
273-
)),
274-
openapitest.WithPath("/pet/{petId}/foo", openapitest.NewPath(
275-
openapitest.WithOperation("GET", openapitest.NewOperation()),
276-
))),
272+
openapitest.WithPath("/pet/{petId}",
273+
openapitest.WithOperation("GET"),
274+
),
275+
openapitest.WithPath("/pet/{petId}/foo",
276+
openapitest.WithOperation("GET"),
277+
),
278+
),
277279
})
278280
h := api.New(app, static.Api{Path: "/mokapi", Dashboard: true})
279281
try.Handler(t,

0 commit comments

Comments
 (0)