I want to deploy my full stack application with AWS amplify but doesn't work - deployment

I'm new and learnig React and mySQL. I've just finished my app with React and mySQL(WorkBench) and I'd like to deploy my app with Amplify. I tried to deploy it through my github repo but URL created for app shows 'Page not found'.
(I'm asked to deploy AWS Amplify from company.)
To be honest, I don't know whether my folder composition is correct to deploy and how to deploy full stack app with amplify.(I could deploy SPA app...)
Below link is my app folder structure.
Below is my app.js code(lambda function with Express)
const express = require('express')
const bodyParser = require('body-parser')
const awsServerlessExpressMiddleware = require('aws-serverless-
express/middleware')
const mysql = require('mysql2')
const connection = mysql.createConnection({
host: 'database-1.clw5xqnhqbio.us-east-1.rds.amazonaws.com',
user: 'root',
password: 'Ryotakagi',
database: 'awstaskmanager'
})
const app = express()
app.use(bodyParser.json())
app.use(awsServerlessExpressMiddleware.eventContext())
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*")
res.header("Access-Control-Allow-Headers", "*")
next()
});
app.get('/tasks', (req, res) => {
const TASK_QUERY = "select * from awstaskmanager.tasks"
connection.query(TASK_QUERY, (err, response) => {
if (err) console.log(err);
else res.send(response)
})
})
app.post('/addTask', (req, res) => {
const ADD_QUERY = `insert into awstaskmanager.tasks (task)
values ('${req.body.task}')`
connection.query(ADD_QUERY, (err) => {
if (err) console.log(err);
else res.send('add task')
})
})
app.delete('/deleteTask/:taskid', (req, res) => {
console.log(req.params.taskid);
const DELETE_QUERY = `DELETE FROM awstaskmanager.tasks where
(taskid=${req.params.taskid})`
connection.query(DELETE_QUERY, (err, res) => {
if (err) console.log(err);
})
})
app.listen(3000, function() {
console.log("App started")
});
module.exports = app
Of course, my local environment is correctly working.
I need to submit this app to my company I want to join, so I REALLY want to complete this app...
So, could you tell me the folder structure is right and how to deploy full stack app which is already finished?

You need to convert your node/express server into Lambda function.
Specific server directory is not necessary, since Amplify won't run this server. So you need to move your node/express code into Lambda function you've created.
If you're using MySQL, you can use AWS RDS using AWS SDK
When using Amplify(serverless stack), all your backend should be separated from the project. Amplify Hosting can't run NodeJS server like for example using pm2
so since you've created an Amplify project, you can add Lambda function using amplify add function command and choose Express server.
and copy your node/express code into that and run amplify push
for your frontend, you can access the node/express server using the name you provided when creating a Lambda function. Basically when Lambda function created and deployed (using amplify push command), Amplify CLI stores the API Gateway URL in your project, in aws-exports.js.
EDIT
If you want to have your React app inside client folder, you need to edit build settings, since you need to cd into client and run npm run build
But if your structure would be like this, you don't need to configure.
> amplify
> node_modules
> public
> src
> package.json
...

Related

ECONNREFUSED during 'next build'. Works fine with 'next dev' [duplicate]

This question already has an answer here:
Fetch error when building Next.js static website in production
(1 answer)
Closed last year.
I have a very simple NextJS 9.3.5 project.
For now, it has a single pages/users and a single pages/api/users that retrieves all users from a local MongoDB table
It builds fine locally using 'next dev'
But, it fails on 'next build' with ECONNREFUSED error
page/users
import fetch from "node-fetch"
import Link from "next/link"
export async function getStaticProps({ params }) {
const res = await fetch(`http://${process.env.VERCEL_URL}/api/users`)
const users = await res.json()
return { props: { users } }
}
export default function Users({ users }) {
return (
<ul>
{users.map(user => (
<li key={user.id}>
<Link href="/user/[id]" as={`/user/${user._id}`}>
<a>{user.name}</a>
</Link>
</li>
))}
</ul>
);
}
pages/api/users
import mongoMiddleware from "../../lib/api/mongo-middleware";
import apiHandler from "../../lib/api/api-handler";
export default mongoMiddleware(async (req, res, connection, models) => {
const {
method
} = req
apiHandler(res, method, {
GET: (response) => {
models.User.find({}, (error, users) => {
if (error) {
connection.close();
response.status(500).json({ error });
} else {
connection.close();
response.status(200).json(users);
}
})
}
});
})
yarn build
yarn run v1.22.4
$ next build
Browserslist: caniuse-lite is outdated. Please run next command `yarn upgrade`
> Info: Loaded env from .env
Creating an optimized production build
Compiled successfully.
> Info: Loaded env from .env
Automatically optimizing pages ..
Error occurred prerendering page "/users". Read more: https://err.sh/next.js/prerender-error:
FetchError: request to http://localhost:3000/api/users failed, reason: connect ECONNREFUSED 127.0.0.1:3000
Any ideas what is going wrong ? particularly when it works fine with 'next dev' ?
Thank you.
I tried the same few days ago and didn't work... because when we build the app, we don't have localhost available... check this part of the doc - https://nextjs.org/docs/basic-features/data-fetching#write-server-side-code-directly - that said: "You should not fetch an API route from getStaticProps..." -
(Next.js 9.3.6)
Just to be even more explicit on top of what Ricardo Canelas said:
When you do next build, Next goes over all the pages it detects that it can build statically, i.e. all pages that don't define getServerSideProps, but which possibly define getStaticProps and getStaticPaths.
To build those pages, Next calls getStaticPaths to decide which pages you want to build, and then getStaticProps to get the actual data needed to build the page.
Now, if in either of getStaticPaths or getStaticProps you do an API call, e.g. to a JSON backend REST server, then this will get called by next build.
However, if you've integrated both front and backend nicely into a single server, chances are that you have just quit your development server (next dev) and are now trying out a build to see if things still work as sanity check before deployment.
So in that case, the build will try to access your server, and it won't be running, so you get an error like that.
The correct approach is, instead of going through the REST API, you should just do database queries directly from getStaticPaths or getStaticProps. That code never gets run on the client anyways, only server, to it will also be slightly more efficient than doing a useless trip to the API, which then calls the database indirectly. I have a demo that does that here: https://github.com/cirosantilli/node-express-sequelize-nextjs-realworld-example-app/blob/b34c137a9d150466f3e4136b8d1feaa628a71a65/lib/article.ts#L4
export const getStaticPathsArticle: GetStaticPaths = async () => {
return {
fallback: true,
paths: (await sequelize.models.Article.findAll()).map(
article => {
return {
params: {
pid: article.slug,
}
}
}
),
}
}
Note how on that example, both getStaticPaths and getStaticProps (here generalized HoC's for reuse, see also: Module not found: Can't resolve 'fs' in Next.js application ) do direct database queries via sequelize ORM, and don't do any HTTP calls to the external server API.
You should then only do client API calls from the React components on the browser after the initial pages load (i.e. from useEffect et al.), not from getStaticPaths or getStaticProps. BTW, note that as mentioned at: What is the difference between fallback false vs true vs blocking of getStaticPaths with and without revalidate in Next.js SSR/ISR? reducing client calls as much as possible and prerendering on server greatly reduces application complexity.

Failed to load API definition Fetch Error, when deployed but fine on localhost

I am upgrading my api from netcore2.1 to 3.1
When I run on localhost the UI works fine.
When I deploy via Azure DevOps and go to the myapplication/myapi/swagger.html url I get
Failed to load API definition
Fetch Error
Service Unavailable /myapi/swagger/v1/swagger/json
Yet I can see the json at
myapplication/myapi/swagger/v1/swagger.json
I have the following
public static IApplicationBuilder UseSwaggerDocumentation(this IApplicationBuilder app)
{
app.UseSwagger(c =>
c.RouteTemplate = "myapi/swagger/{documentName}/swagger.json"
);
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/myapi/swagger/v1/swagger.json", "Versioned API v1.0");
c.RoutePrefix = "myapi/swagger";
});
return app;
}
I am using
Swashbuckle.AspNetCore (5.2.0)
I found the following worked.
public static IApplicationBuilder UseSwaggerDocumentation(this IApplicationBuilder app)
{
app.UseSwagger(c =>
c.RouteTemplate = "myapi/{documentName}/swagger.json"
);
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("./v1/swagger.json", "Versioned API v1.0");
c.RoutePrefix = "myapi";
});
return app;
}
The docs state
If using directories with IIS or a reverse proxy, set the Swagger
endpoint to a relative path using the ./ prefix. For example,
./swagger/v1/swagger.json. Using /swagger/v1/swagger.json instructs
the app to look for the JSON file at the true root of the URL (plus
the route prefix, if used). For example, use
http://localhost://swagger/v1/swagger.json instead
of
http://localhost:///swagger/v1/swagger.json.
However unfortunately my solution doesn't work with Autorest.
Thus I asked another question

How to publish a custom nuxt plugin + development workflow

I am looking for some best practices for publishing and developing nuxt plugins. I would like to write a plugin which gives our web applications the possibility to request oauth tokens from everywhere. I have written this plugin localy in my project and it works. Now my target is to move the code to a seperate plugin project and upload it to npm so every one in my company might use it easily. Are there any guides how to setup a nuxt plugin project? I found several guides for creating vue-plugins but the structure of them are a bit different to nuxt. I do not have a install method. Because my plugin simply wraps vuex store methods defined in oAuthStore.js as global methods, which can be used when I register my plugin in nuxt.config.js.
Vue plugins seems to work a bit different.
I upload a vue-plugin with an install method. When I try to import it and run my application on dev server (npm run dev) i always get the error message:
This dependency was not found: * my-plugin in ./plugins/vuex-persisted.js friendly-errors 16:55:24
friendly-errors 16:55:24
To install it, you can run: npm install --save my-plugin
My plugin has been uploaded to npm correctly and I have used it by executing npm install --save my-plugin so it has an entry on dependency list in package.json.
When I try to npm-link my-plugin I get the same error. This is the only way I know for rapid prototyping because I do not want a npm publish every time I want to test something. Does everyone know a way for a better developing workflow for working on nuxt plugins?
Thanks for any help.
Best regards
Moritz
/** oAuthPlugin.js **/
import oAuthStore from './oAuthStore.js'
import Cookies from 'js-cookie'
import createPersistedState from 'vuex-persistedstate'
export default ({store, isHMR, app}, inject) => {
app.store.registerModule('oAuth', oAuthStore );
var me = app;
inject('getOAuthCredentials', () => {
var data = {};
if(app.$store) {
var data = app.$store.getters["oAuth/getAuthCredentials"];
}
return data;
});
inject('requestOAuthCredentials', (data) => {
if(me.store) {
me.store.commit("oAuth/requestOAuthCredentials", data);
}
});
if (isHMR) return
// add persisted state as a vue mounted mixin
if (!app.mixins) {
app.mixins = []
}
app.mixins.push({mounted () {
createPersistedState({
key: 'vuex-persisted',
paths: ['oAuth'],
storage: {
getItem: key => Cookies.get(key),
setItem: (key, value) => Cookies.set(key, value, {expires: 3}),
removeItem: key => Cookies.remove(key)
}
})(store);
}});
}
/** nuxt.config.js **/
/*
** Plugins to load before mounting the App
*/
plugins: [
{ src: '~/plugins/vuex-persisted', ssr: false },
{ src: '~/plugins/oAuthPlugin.js' }
],

In VSTS, async Jest tests that connect to dockerized ArangoDB database time out

I'm trying to run jest tests with a Visual Studio Team Services build. These tests run fine and pass locally, but timeout when I run them in VSTS. For each async test that connects to the database, I get
Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.
Here's my setup:
graphql API using Apollo Server
ArangoDB database insider a docker container
A typical test looks like this:
const database = require('../models')
...
describe('database setup', () => {
it('sets up the database and it exists', () => {
console.log(database.db)
const collection=database.db.collection('agents')
console.log(collection)
return database.db.exists().then((result) => {
expect(result).toBeTruthy()
}).catch(err => {console.log(err)})
.then(x => console.log(x))
})
}
...
describe('help functions', () => {
it('gets edge count for a node', async () => {
let result = await database.getEdgeCount('nodes/1', 'inbound')
expect(result).toBeGreaterThan(2)
})
})
I'm running the tests in VSTS with an NPM task. The YAML for this task is basic:
steps:
- task: Npm#1
displayName: npm test
inputs:
command: custom
workingDir: api
verbose: false
customCommand: 'test --runInBand'
I know that the tests are connecting to the database because I can console.log the database object and get the database information.
Other things I've tried:
Promise tests that don't hit the database, such as
it('foo', async () => {
await Promise.resolve()
expect(1).toEqual(1)
})
These pass
Increasing the timeout to 30000. This causes a couple of the tests with database calls to return null.
I was able to fix this, and I think there were two issues going on:
The API was not actually connecting to the database. I was able to fix this by creating a new docker network and attaching both the database and VSTS build agent, as described in this other answer
The tests were starting before the database had completely started up. I added a sleep command in a bash script before the tests which seemed to fix this.

Is Postman Java based tool?

I am testing a rest web service using PostMan tool. Is PostMan a java based client tool?. I am able to run the service using a Java based client, but get an error with .net client.
postman is a tool for testing webservices and it does not depend on any language provided your rest endpoints are up and running everything should work no matter the language used in the backen
No, but you can run Newman as a JavaScript module like :
var newman = require('newman');
newman.run({
collection: '/path/to/collection.json',
reporters: 'myreporter',
reporter: {
myreporter: {
'option-name': 'option-value' // this is optional
}
}
}, function (err, summary) {
if (err) { throw err; }
console.info('collection run complete!');
});