I have used swagger-express npm module to configure api-documentation parallel to my server so it help devs to keep track of all apis.
What I have folder structure is
/
/api
swagger/
swagger.json
swagger.yml
/swagger /*Having all the index file and configs as given their like public dir*/
My middle-ware configuration is like this
var swagger = require('swagger-express');
app.use(swagger.init(app, {
apiVersion : '1.0',
swaggerVersion: '1.0',
swaggerURL : '/swagger',
swaggerJSON : 'api/swagger/swagger.json',
swaggerUI : './swagger/',
basePath : 'http://localhost:1222',
info : {
title : 'swagger-express sample app',
description: 'Swagger + Express = {swagger-express}'
},
apis : ['api/swagger/swagger.yml'],
middleware : function (req, res) {}
}));
My server is running at port 1222. Now though the SwaggerUI is loaded successfully but its reading api's from wordnik's domain.
How would it read apis from my swagger.yml
If I am mentioning the swagger.yml then whats the relevancy and use of swagger.json
What is discoverURL in SwaggerUI? If I am mentioning my json path (http://localhost:1222/swagger/) in that it ends with error like 'discoveryUrl basePath must be a URL.'
Is their any way I can list all apis in parallel to server? so It can be tested as well? I want it with swagger.
hey just try this https://www.npmjs.com/package/hapi-swagger
npm install hapi-swagger --save
npm install inert --save
npm install vision --save
const Hapi = require('hapi');
const Inert = require('inert');
const Vision = require('vision');
const HapiSwagger = require('hapi-swagger');
const Pack = require('./package');
const server = new Hapi.Server();
server.connection({
host: 'localhost',
port: 3000
});
const options = {
info: {
'title': 'Test API Documentation',
'version': Pack.version,
}
};
server.register([
Inert,
Vision,
{
'register': HapiSwagger,
'options': options
}], (err) => {
server.start( (err) => {
if (err) {
console.log(err);
} else {
console.log('Server running at:', server.info.uri);
}
});
});
server.route(Routes);
Related
Currently we are trying to run the nodejs server in angular application(net core -angular -spa).We went through this source-
https://www.simplilearn.com/tutorials/angular-tutorial/what-is-angular-node
As per the project we went on creating the angular application and set the proxy based upon the link : https://angular.io/guide/build#proxy-multiple-entries
The Step we are following this:
Step 1: Creation Node Server, which is working individually.
The 504 error shows here.
var express = require('express');
var app = express();
app.use(express.static("myApp")); // myApp will be the same folder name.
// PORT
const port = process.env.PORT || 8000
app.get('/', (req,res) => {
res.send('App Works !');
});
app.get('/externalapi/get', (req, res) => {
console.log(req);
console.log('App Works !');
res.send('Got Files!');
return "Got Files";
});
app.listen(port, () => {
console.log(`Server listening on the port no.:${port}`);
});
Step 2 : Proxy.config.js (not json)
const PROXY_CONFIG = [
{
context: [
"/weatherforecast",
],
target: target,
secure: false,
headers: {
Connection: 'Keep-Alive'
}
},
{
context :[
"/externalapi/*",
],
target : "http://localhost:8000",
secure: false,
changeOrigin: true,
}
]
module.exports = PROXY_CONFIG;
Step 3: Creation of the Services
export class ExampleServices{
_nodeUrl : any = '/externalapi/';
constructor( private httpClient: HttpClient){
}
mergeExamples(files:any) : Observable<any> {
console.log(this._nodeUrl);
return this.httpClient.get(this._nodeUrl+"get", files);
}
}
There are two from us ->
Why 504 Error occurs in this code ?Is it due to https-> http calling?
Is there any possibility to run the nodejs command from parent folder itself(currently the externalapi is inside the angular app, have its own node_modules)
Kindly help us with relevant answer and supporting documents.
My api has stopped working, previously it worked fine and as far as i am aware I have changed nothing. When i tested my endpoint i received an internal server error.
Here is a link to my hosted api https://frozen-scrubland-34339.herokuapp.com/api
I have just checked some of my other apis and none are working either, same message. it appears my code isnt the issue but postgres itself?
Any help on what to do would be appreciated
When i tried to npm run prod to re-push it to heroku i received: 'Error: The server does not support SSL connections'
Again this was never an issue previously when it worked.
I imagine i have changed something with heroku itself by accident?
app.js
const express = require("express");
const app = express();
const apiRouter = require("./routers/api-router");
const cors = require("cors");
const {
handle404s,
handlePSQLErrors,
handleCustomError,
} = require("./controllers/errorHandling");
app.use(cors());
app.use(express.json());
app.use("/api", apiRouter);
app.use("*", handle404s);
app.use(handlePSQLErrors);
app.use(handleCustomError);
module.exports = app;
connection.js
const { DB_URL } = process.env;
const ENV = process.env.NODE_ENV || "development";
const baseConfig = {
client: "pg",
migrations: {
directory: "./db/migrations",
},
seeds: {
directory: "./db/seeds",
},
};
const customConfigs = {
development: { connection: { database: "away_days" } },
test: { connection: { database: "away_days_test" } },
production: {
connection: {
connectionString: DB_URL,
ssl: {
rejectUnauthorized: false,
},
},
},
};
module.exports = { ...baseConfig, ...customConfigs[ENV] };
I have a React front-end that makes requests to the github API. I initially wrote the project to make use of an Express proxy server to help keep some environment variables private. I have the front-end of the project deployed on Netlify and since my little server only has 2 routes (for fetching a user's profile and repos, independently) I didn't think it made sense to deploy the back end somewhere else, and figured I'd just use the serverless-http package to wrap my server and make it essentially a Netlify Lambda function.
The issue: I have the project working locally when I set the NODE_ENV to both production and development, with a slightly modified webpack.config proxy setting (that is to say, it's slightly different than I need it to be to run it locally directly using the Express server). Further, I can query the routes on the deployed project with Postman and it appears to correctly return the data from the endpoint at the GitHub API. At present, the frontend is showing an error that indicates that there is a JSON parsing error (unexpected character at column 1)... I have had this error in local development when trying to make this work there and it was because the request initiating on the frontend was not making its way to the proxy server. Realistically my error handling for the project is dog-shit and so I don't have more info at present.
As the code is written, requests are still proxied through the serverless functions.
My feeling is this is an issue with how I have deployed things. I've spent a few hours going through the docs and I really don't know what I've done wrong, so I'm hoping someone familiar with Netlify and their implementation of serverless functions has an idea about why this isn't working.
I'm using Node v11.10.0.
For reference, the Express API I wrote is as follows:
const express = require('express');
const bodyParser = require('body-parser');
const axios = require('axios');
const serverless = require('serverless-http');
require('dotenv').config();
// Initialize app
const app = express();
const router = express.Router();
const port = process.env.PORT || 3000;
// Configuration
app.use(bodyParser.json({ type: 'application/json' }));
const routerBasePath = (process.env.NODE_ENV === 'development')
? `/index`
: `/.netlify/functions/index`
app.use(routerBasePath, router);
console.warn('Node environment: ', process.env.NODE_ENV)
// Constants
const id = process.env.GITHUB_CLIENT_ID;
const secret = process.env.GITHUB_CLIENT_SECRET;
const params = `?client_id=${id}&client_secret=${secret}`
// Route(s)
router.post('/profile', (req, res) => {
const { username } = req.body;
const endpoint = `https://api.github.com/users/${username}${params}`;
axios({
method: 'get',
url: endpoint,
})
.then(response => {
res.status(200)
res.send(response.data)
})
.catch(error => {
console.log('Error with Axios profile res: ', error)
res.send({ error })
})
return
})
router.post('/repos', (req, res) => {
const { username } = req.body;
const endpoint = `https://api.github.com/users/${username}/repos${params}&per_page=100`;
axios({
method: 'get',
url: endpoint,
})
.then(response => {
res.status(200)
res.send(response.data)
})
.catch(error => {
console.log('Error with Axios repos res: ', error)
res.send({ error })
})
return
})
// DJ, spin that shit:
app.listen(port, () => console.log(`App is running on port ${port}`));
process.on('SIGINT', () => {
console.log(`Process on port ${port} successfully terminated.`);
process.exit();
})
// Serverless
// app.use('/.netlify/functions/index', router);
module.exports.handler = serverless(app);
The relevant portion of webpack.config:
mode: process.env.NODE_ENV === 'production'
? 'production'
: 'development',
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000',
pathRewrite: { '^/api': '.netlify/functions/index' }
}
},
historyApiFallback: true
},
The relevant code from the front-end:
function getProfile(username) {
return fetch('/api/profile', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ 'username': username })
})
.then(res => {
return res.json()
})
.then(profile => {
if (profile.message) {
throw new Error(getErrorMsg(profile.message, username))
}
return profile
})
}
function getRepos(username) {
return fetch('/api/repos', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ 'username': username })
})
.then(res => {
return res.json()
})
.then(repos => {
if (repos.message) {
throw new Error(getErrorMsg(repos.message, username))
}
return repos
})
}
And my package.json:
"scripts": {
"build": "NODE_ENV='production' webpack",
"build-for-windows": "SET NODE_ENV='production' && webpack",
"build-for-netlify": "NODE_ENV='production' webpack && npm run build:lambda",
"start": "concurrently \"webpack-dev-server\" \"npm run start:lambda\"",
"server": "nodemon server/index.js",
"start:lambda": "NODE_ENV='production' netlify-lambda serve ./server",
"build:lambda": "netlify-lambda build ./server"
},
"babel": {
"presets": [
"#babel/preset-env",
"#babel/preset-react"
],
"plugins": [
"#babel/plugin-proposal-class-properties",
"syntax-dynamic-import"
]
},
"proxy": "http://localhost:3000"
[build]
command = "npm install && npm run build-for-netlify"
functions = "functions"
publish = "dist"
To test this locally, I've run the npm run start script, changing the NODE_ENV between production and development. When it's in development mode, the routes are accessible via /index (as seen in the express API) and when it's in production they're accessed via ./netlify/functions/index, and the behavior is as expected both in the local environment and from Postman.
I'm fairly new to setting up this kind of environment so I'm sure there are some dumb errors but I'm at a loss for what to search for at this point. I did see something about needing to bundle your Netlify Functions for deploy but I am not sure if the build step handles that or not.
Thanks in advance all, this has been a headscratcher for me.
EDIT1: Added netlify.toml configuration as well.
EDIT2: Added Node version info.
EDIT3: Adding info about error
I have a form on my site and I want to send the data from fields to my email. I am using nodemailer and node js for this things. But when I submit form I have an 404 error on POST request.
form-component:
this.http.post('api/sendForm',{
to: environment.contactUsEmail,
from: 'zzz',
subject: 'zzz',
mailInfo: contactUsData,
}
).subscribe(() => {
this.cooperationFormGroup.reset();
});
server.ts: (path:backend/server.ts) folder backend is near folder src
const express = require('express');
const bodyParser = require('body-parser');
const nodemailer = require('nodemailer');
const PORT = process.env.PORT || 3000;
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post('api/sendForm', (req, res) => {
const payload = req.body;
const mailInfo = payload.mailInfo;
const transporter = nodemailer.createTransport({
service: 'gmail',
host: 'smtp.gmail.com',
secure: 'true',
port: '465',
auth: {
user: 'email',
pass: 'pass',
}
});
const text = [...];
const mailOptions = {
from: 'zz',
to: payload.to,
subject: payload.subject,
text: text.join('\n'),
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
res.status(200).json({
message: 'successfully sent!'
})
}
});
});
app.listen(PORT, () => {
console.log(`Server is running in ${PORT}`);
});
I run server.ts in the folder backend using node server.ts and run angular app using npm start
As mentioned above in my comment: you need to pass the complete URL of your backend to post: use http://localhost:3000/api/sendForm instead of api/sendForm.
However, to manage different values during development and production, you might want to use environment.ts and environment.prod.ts:
environments/environment.ts:
export const environment = {
production: false,
urlToBackend: 'http://localhost:3000'
}
environments/environment.prod.ts:
export const environment = {
production: true,
urlToBackend: 'http://<IP>:3000'
}
service.ts:
While building the production build with npm run build, environment.ts will be replaced by environment.prod.ts as mentioned in the angular.json (see the object fileReplacements).
import { environment } from '../../environments/environment';
...
#Injectable()
export class AppService {
url = environment.urlToBackend;
constructor(private http: HttpClient) {
}
foo() {
return this.http.post(`${this.url}/api/sendForm`,{ ... });
}
}
My code is not accurate and you need to arrange it for your needs. However, I hope, you get the idea.
You need to mention the complete backend server URL in the first argument of the .post.
Change 'api/sendForm' to 'Your complete backend url'.
this.http.post( 'complete backend server url' ,
since you are running the node server on PORT 3000. Your backend URL will be http://localhost:3000/api/sendForm
I'm finding some difficulties to follow the guide for hapijs-react-views package setup (npm hapi-js-react-views).
I can run the server but I only get this error on localhost:3000
{"statusCode":500,"error":"Internal Server Error","message":"An internal server error occurred"}
My repo on github is: hapi-react GitHub
My code is:
-routes
--index.js
-views
--index.jsx
-app.js
-package.js
// routes/index.js
exports.index = function(request, reply){
reply.view('index', { name: 'John' });
};
// views/index.js
var HelloMessage = React.createClass({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
module.exports = HelloMessage;
//app.js
var hapi = require('hapi');
var vision = require('vision');
var path = require('path');
var engine = require('hapijs-react-views')();
// Create a server with a host and port
var server = new hapi.Server();
server.connection({
host: 'localhost',
port: 3000
});
// Register Hapi plugins
server.register(vision, function (err) {
if(err) throw err;
});
var options = { jsx: { harmony: true } };
server.views({
defaultExtension: 'jsx',
engines: {
jsx: require('hapijs-react-views')(options), // support for .jsx files
js: require('hapijs-react-views')(options) // support for .js
},
relativeTo: __dirname,
path: 'views'
});
// Add the route
server.route({
method: 'GET',
path: '/',
config: {
handler: require('./routes').index
}
});
// Start the server
server.start((err) => {
if (err) {
throw err;
}
console.log('Server running at:', server.info.uri);
});
//package.json
"dependencies": {
"hapi": "^13.4.1",
"hapijs-react-views": "^0.7.3",
"react": "^15.1.0",
"vision": "^4.1.0"
}
Can you help me?
Thanks in advance.
For anyone who sees this in the future, there's a working example of jsx rendering with vision here: https://github.com/hapijs/vision/tree/master/examples/jsx
I was having this exact issue. The documentation doesn't say but you still require React in your view files. That fixed the problem for me.