using req.params vs req.query in Next.js dynamic api routes - javascript

I am trying to access params in my Next.js API routes. I am just wondering why in order to access a certain dynamic route id I must use req.query when normally in express I would access the id via params. Is req.query the correct way of accessing the id?
I have the following api folder structure.
/pages
/api
/posts
-index.js
-[postId].js
In my [postId] file I have the following
function handler(req, res) {
// shows undefined
console.log(req.params);
const postId = req.params.postId;
and my api call is as follows:
fetch(`/api/posts/${id}`)

Referring to nextJs docs, all examples uses req.query to get the id or other parameters:
import { useRouter } from 'next/router'
const Post = () => {
const router = useRouter()
const { pid } = router.query
return <p>Post: {pid}</p>
}
export default Post
So there's nothing wrong with this approach.
Nextjs doesn't explicit says why they use query instead of params, but in the section about dynamic routes you can get some clues:
the route /post/abc?foo=bar will have the following query object:
{ "foo": "bar", "pid": "abc" }
Probably they use query as a way to join both params and query in one object or it's just more convenient to use that way, so as there's no reference about it you don't have to care that much, just use the query and be happy.

Related

Next Js Server Side Api Read and Write JSON

I'm trying to write a basic local api for myself using Next.js, it is a timeline generator, and I am stuck at actually reading the file from the api folder.
What do I want in my local aplication:
1.A simple page where I can input an event, with a date and description
2.Open a list.json file somewhere and push that new event to that json file, writing on it.
What I am currently doing and where I am stuck:
I am aware we cant write on files on the client side, so I started looking at the api routes in next js to access the JSON file, but I cannot even manage to read it!
I have an api folder inside pages folder, and in this api folder I have two files: one is the list.json file, where I previously manually write some events with respective dates; and the other is getlist.js, with this code:
var fs = require('fs');
export default function getList(req, res) {
const rawList = fs.readFile('list.json');
var list = JSON.parse(rawList);
res.json(list);
}
Now on the pages folder I have a index.js file where I try to access this getlist.js api using getStaticProps(), like this:
import getlist from './api/getlist'
export async function getStaticProps(){
var list = getlist();
return {
props: {
list
}
}
}
I have tried using other stuff, like the fecth function, to get to getlist.js, but nothing I do seems to work.
Can anyone help me?
And since I'm already in here, how would I manage to get the input from the form I already have in my client side page and write it to that list.json file in my api folder?
There are two ways how you can read json in next.js:
Import inside getStaticProps [https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation]
export async function getStaticProps(context){
const example = await import('./api/example.json');
return {props: {example: example.default}}
}
Import or read in handler function inside api folder [https://nextjs.org/docs/api-routes/introduction]:
const fs = require('fs');
export default async function handler (req, res) {
const example = await fs.readFile('./example.json');
return res.status(200).json({example});
}
In order to write *.json file you need to send request with value to the server api (handler from api folder that was mentioned before).
That's how the part to write json will look like:
const fs = require('fs');
export default async function handler(req, res) {
//...
if (req.method === 'POST'){
fs.writeFileSync('./example.json', JSON.stringify(req.body))
return res.status(200).json({});
}
//...
}

How to call restfull API inside router using express

I want to retrieve data that is at this link: https://api.rajaongkir.com/starter/cost using express.js.
I created the Single Page Application website using react.js for frontend so i need to call this route : /shipping/check/cost in my backend for get the data. but i dont know how to request inside router express.
I have never done a Restful API from someone else's website.
I just copied what was in the documentation, but in the documentation using the node.js not express.js. https://rajaongkir.com/dokumentasi/starter#cost-response
when I run this I get nothing.
My routes
import {Router} from 'express';
import * as ShippingRouter from './controller'
const routes = new Router();
routes.post('/shipping/check/cost',ShippingRouter.checkCost);
export default routes;
Controller
import db from '../../config/conn';
import keys from '../../config/keys';
import jwt from 'jsonwebtoken';
import qs from 'querystring';
import request from 'request';
export const checkCost =(req,res)=>{
var options = {
"method": "POST",
"hostname": "api.rajaongkir.com",
"port": null,
"path": "/starter/cost",
"headers": {
"key": "mykey",
"content-type": "application/x-www-form-urlencoded"
}
};
var reqCost= https.request(options,function(ress){
var chunks = [];
ress.on("data", function (chunk) {
chunks.push(chunk);
});
ress.on("end", function () {
var body = Buffer.concat(chunks);
res.json(body.toString());
});
})
reqCost.write(qs.stringify({
origin: '501',
destination: '114',
weight: 1700,
courier: 'jne'
}));
reqCost.end();
}
The first thing I would check is if the POST HTTP verb you are using is the correct one. You said you wanted to get data from the API, in this case, you should be using GET instead of POST (check the API documentation to know more).
Besides that, please check this repository where I'm using express and how I handle calls.

Differences between query routes in nextjs using next-routes

I'm working on a project with next.js and Reactjs that uses a lot of different languages. So I need to change the language url. Example:
www.example.com/es/entradas
www.example.com/en/tickets
www.example.com/de/eintrittskarten
To make routes I saw that there is a module that helps me: next-routes
https://github.com/fridays/next-routes
There are a lot of url and I'm working with a CMS, so my clients will be able to add more, so routes can't be harcoded. I thought to pass the url with queries, like this:
const routes = require('next-routes');
module.exports = routes()
.add('index', '/:lang?')
.add('tickets', '/:lang?/:ticket')
.add('hotel', '/:lang?/:hotel');
My surprise (as you might see), it doesn't work because routes doesn't see the difference between these two last routes. If I write:
www.example.com/en/tickets
It will go correctly to my page "tickets" but if I write
www.example.com/en/hotel
It will go again to my page "tickets" and not to "hotel"
Do you know any way about how could I make this?
In my project I have these files related about routes:
server.js
const next = require('next');
const { createServer } = require('http');
const routes = require('./routes');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dir: './src/shared', dev });
const handle = routes.getRequestHandler(app);
app.prepare()
.then(() => {
createServer(handle)
.listen(3001, (err) => {
if (err) throw err;
console.log("> Ready on http://localhost:3001");
});
});
routes.js
const routes = require('next-routes');
module.exports = routes()
.add('index', '/:lang?')
.add('tickets', '/:lang?/:ticket')
.add('hotel', '/:lang?/:hotel');
The request for /en/hotel is going to the "ticket" route because it is actually matching it.
This is because of the : in front of the word "ticket" in the route. A : will turn a section of a route into a parameter with that name.
So instead what you probably want is:
module.exports = routes()
.add('index', '/:lang?')
.add('tickets', '/:lang?/ticket')
.add('hotel', '/:lang?/hotel');

How to change graphql endpoint url name

I'm just start using graphql with apollo client, I have graphql server setup and is running localhost:4000, and here is my client
index.js
const client = new ApolloClient({
uri: "http://localhost:4000/graphql",
cache: new InMemoryCache()
});
blog.js
const GET_BLOG = gql`
{
post(id:"5ab2b46d941953bf614e2617") {
title
body
user {
name
email
}
}
}
<Query query={GET_BLOG}>...</Query>
I got everything working, my question is there way I can change the graphql endpoint url name, so instead of graphql, can I have something like /graphql/post, /graphql/user, I have the scheme in graphql server, but if I do two call, it will just return two /graphql in network tab
SERVER.applyMiddleware({
app: APP,
path: '/newEndPoint'
});
Set path attribute within applyMiddleWare Options object. Now visit
localhost:<port>/newEndPoint for the grap
As far as I know, graphql only use one endpoint url name, in your case is http://localhost:4000/graphql , if you want separated endpoint, it is just like REST routing

Global access of config from database in express js

I am using expressjs and want to store project config variables in database for some reason. What is best way to access config variables from database so I will not need to query database on each router i am loading.
Should I use app.locals?
To do this, I don't export the "router" directly but a function that accept an argument which will receive the config. Here's an example :
// router.js
module.exports = function(database) {
return {
getLogin: function(req, res) {
// database exist here
}
}
}
// app.js without the creation of app and database
var app = express();
var database = require('./database');
var router = require('./router')(database)
app.get('/login', getLogin);
This way, you have the modularity and the possibility to interact easily with the database.

Categories