In the new V3 version there is no option "useBackendForStorage, backendEndpoint" to set an endpoint to save the json:
https://github.com/swagger-api/swagger-editor/blob/2.x/docs/config.md#backends
Is the feature in roadmap?
You can use dirty hack, just replace src/plugins/local-storage/index.js with
```import PetstoreYaml from "./petstore"
const CONTENT_KEY = "swagger-editor-content"
let localStorage = window.localStorage
export const updateSpec = (ori) => (...args) => {
let [spec] = args
ori(...args)
saveContentToStorage(spec)
}
export default function(system) {
// setTimeout runs on the next tick
setTimeout(() => {
var xhr = new XMLHttpRequest();
xhr.open('GET', BACKEND_URL, false);
xhr.send();
if (xhr.status != 200) {
console.log( xhr.status + ': ' + xhr.statusText );
} else {
system.specActions.updateSpec(xhr.responseText)
}
}, 0)
return {
statePlugins: {
spec: {
wrapActions: {
updateSpec
}
}
}
}
}
function saveContentToStorage(str) {
var xhr = new XMLHttpRequest();
xhr.open('PUT', BACKEND_URL, true);
xhr.send(str);
if (xhr.status != 200) {
console.log( xhr.status + ': ' + xhr.statusText );
}
}
```
don't forget change BACKEND_URL. Next step - edit src/plugins/editor/components/editor-container.jsx and update DEBOUNCE_TIME it's delay time before save, 800 ms too fast for me :)
I subscribe to the expected realization of save to backend
Where are the docs for Editor 3.x?
With the help of the hints in https://github.com/swagger-api/swagger-editor/issues/1471, I've got the "saving to backend" feature working with a modified index.html that is identical to the one comes with swagger-editor-dist but with the following scripts:
<script>
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
const SpecUpdateListenerPlugin = function() {
return {
statePlugins: {
spec: {
wrapActions: {
updateSpec: function(oriAction) {
return function(spec) {
var url = getParameterByName('url');
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.send(spec);
if (xhr.status != 200) {
console.log( xhr.status + ': ' + xhr.statusText );
}
return oriAction(spec);
};
}
}
}
}
}
}
window.onload = function() {
// Build a system
const editor = SwaggerEditorBundle({
dom_id: '#swagger-editor',
layout: 'StandaloneLayout',
presets: [
SwaggerEditorStandalonePreset
],
plugins: [
SpecUpdateListenerPlugin
]
});
window.editor = editor;
}
</script>
I have the modified editor served on http://localhost/editor and all my spec on http://localhost/specs (with GET and PUT). Then the link to edit a specification is http://localhost/editor/?url=/specs/file.yaml
Hi Jemerald,
Thanks for the solution given to edit the document on server. I have followed the steps you mentioned above but I have observed that in browser console its showing "Failed to load resource: the server responded with a status of 403 (Forbidden)" when trying to execute the method xhr.send(spec). Can you please help me is there any solution to fix the 403 error.
Regards,
Suresh
@sureshui18 the 403 error would come from your webserver and has nothing to do with the code above.
You will need to make sure you can access the yaml files served by your webserver. Try test it with curl or similar tools
@jemerald, I am trying to understand your comment above "I've got the "saving to backend" feature working ".
Am I right to understand that you did:
1) npm i swagger-editor-dist
2) Modified ./node_modules/swagger-editor-dist/index.html, replacing the window.onLoad script with what you included above.
I have swagger-editor-dist working, I tried the modification suggested above. swagger-editor still works, but when I select the menu option "File -> Save as JSON", the browser still downloads the swagger as a JSON, instead of trying to store it to a backend.
I guess I am missing something.
Hey @MattGurneyAMP, @jemerald's plugin above automatically sends requests when Swagger Editor's content changes, not when the File menu is used 馃槃
Thanks @shockey, that is useful to know. However, I am at a loss to understand what changes I have to make to either the github source of swagger-editor or the npm distribution of swagger-editor-dist to enable the write to backend feature. I know how to setup my own node express backend to serve and save swagger files. I just don't know how to make swagger-editor call it during saving (which you tell me is triggered when editor content changes). I use the url= feature to open swagger files in the editor, and I serve those from my node express server successfully.
Just guessing, but do I need to make the change to src/plugins/local-storage/index.js, as suggested by @iromanov-nk, then make the change to the src file representing ./node_modules/swagger-editor-dist/index.html as suggested by @jemerald ?
@MattGurneyAMP my post above already included the setup. Here's how things work under the hood:
http://localhost/editor/?url=/specs/file.yaml (if the specs is hosted on a different server from the editor, just need to include the full URL: http://localhost/editor/?url=http://server2/specs/file.yaml)index.html is servedGET http://localhost/specs/file.yamlPUT http://localhost/specs/file.yaml with the body being the entire payloadServer side code would handle GET/PUT methods on path /specs/* to do the reading and writing of files. Mine is just a simple express server:
var route = app.route(`/specs/*`);
route.get(function (req, res) {
// substring(1) removes the initial slash and turns it into relative path, which matches the folder structure on the server
let path = decodeURI(req.path).substring(1);
res.send(fs.readFileSync(path));
});
route.put(function (req, res) {
let path = decodeURI(req.path).substring(1);
let rawBody = '';
req.on('data', function(chunk) {
rawBody += chunk;
});
req.on('end', function(){
fs.writeFileSync(path, rawBody);
res.send(fs.readFileSync(path));
});
});
Thanks @jemerald, I understand, it is working now. This is a great feature. What I didn't understand before is that I can use either the packaged swagger-editor-dist or the full source and the only code change needed was to change node_modulesswagger-editor-distindex.html (or equivalent unpackaged source), and replace the window.onLoad script with what you included above.
Additionally as you mention above a simple node express server is needed to act as the backend.
Sorry for any confusion and thanks again for your help and a great project :).
I may attempt to extend this solution to integrate into a more fully featured backend with more of a workflow around versioning, update history, save on demand instead of automatic etc. If anyone has any ideas on a npm project which could act as the back end Content Management System, let me know.
@MattGurneyAMP check out Netlify CMS, which lives under version control and already stores its data in YAML. Not sure if they have the necessary APIs for automated modification though.
Ok, thanks @shockey will do.
For those interested, I've written a wrapper package for the swagger-editor 3.x https://www.npmjs.com/package/openapi-editor It uses a similar solution as described by @jemerald
Most helpful comment
For those interested, I've written a wrapper package for the swagger-editor 3.x https://www.npmjs.com/package/openapi-editor It uses a similar solution as described by @jemerald