Let's say I have a /createPost POST endpoint in my nestjs backend. The request and response object should be fully typed in the backend via the DTO. However, how do I bring these types into the frontend? I would like to have a typed post request object, so I can not enter invalid fields or missing fields in the post body. I would also like to have a typescript interface for the response. I want to REUSE the code from the backend. What's the best way to go about this? Is there some sort of type generator library?
Maybe you can create a monorepo using nx workspace https://nx.dev/.
With that you can share models between all apps.
you can use graphql, it can shares types with front
Another thing you could try is to create a Github package that you install (can be private and is free as opposed to doing this on NPM).
Things to remember after you have published the package on your Github organization:
Add a .npmrc file in the root folder of your project and write the following:
#your-organization-name:registry=https://npm.pkg.github.com registry=https://registry.npmjs.org
Remember that you will need to npm login for this to work like this:
npm login --registry=https://npm.pkg.github.com
Username: your github username
Password is a token you create from Github -> Settings -> Developer settings.
I know I havent fully described the flow for you here on how to publish a package to Github, but the general idea should be clear.
Good luck!
Firstly, I just wanted to say that this is my first web application project. I've spent the past few days trying to find answers on how to essentially put the frontend and backend together. I have a lot of questions, but the main one I want answered is on how to return my frontend 'final product' from a backend endpoint.
This is what I understand (please correct me if I'm wrong):
The frontend code is run by the client (browser).
When the client interacts with the webpage, the frontend makes API calls to the backend to retrieve/modify data, as necessary.
The backend and frontend is often developed separately, and could be hosted on separate servers.
It is, however, possible (and maybe simpler) to host it on a single domain/server. I am hoping to do this, in order to avoid a whole set of issues with CORS.
Then comes the following problem:
When I want to test out my front end and see how it's coming along, I just run npm run start. I then go to the given url (usually http://localhost:8080/) and I have access to the frontend that I've developed. And when I want to deploy it, I run npm run build, which gives me a dist folder (bundled together and minified).
If I want to run and test my backend locally, as I am using FastAPI, I simply run uvicorn main:app --reload.
How to put the two together? More specifically, in my backend code, how do I return the product of my frontend work (i.e., the dist folder?). I've tried the following (simplified):
#app.get("/", response_class=HTMLResponse)
def root():
return open("../frontend/dist/index.html", "r").read()
but, of course, this only gives me the static html without the React components.
I realize this post may be loaded with incorrect assumptions and poor practices (in which case, my apologies! and I would appreciate any corrections/suggestions.) However, if the following questions could be answered, I would greatly appreciate it. These are questions I have that will hopefully help me test my whole web application locally on my computer.
How do I return the product of my frontend work for the GET request at the domain root endpoint?
If there is a page A, page B, and page C for my web app, each with url www.example.com/A, www.example.com/B, and www.example.com/C do I have to create three separate React frontend projects? I.e., equivalent of having three dist folders? What is the standard way this is handled?
These are good questions and it is certainly possible. I will tell you what I do, with the caveat that there may be a better way...
I'm using Vue instead of React, but its build process also sends static html, js and css to a dist/ directory, so the process should be about the same.
First you can copy the dist/index.html file you mention into your FastAPI templates/ directory. You will use your FastAPI route to serve that file as a Template.
Then copy your js and css into a static/ directory and make sure FastAPI knows about both static and templates.
from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")
#app.get("/")
async def serve_spa(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
You may need to set something in React in order for your build to know that the js and css will live in a dir called static. For Vue, there is the assetsDir option within vue.config.js
For your question about handling different paths, like example.com/a and example.com/b, it depends how you want to handle those requests. Are you wanting your single react app to handle all of those routes?
If that is the case, you may want to see also: How to capture arbitrary paths at one route in FastAPI?
One option is to copy the serve_spa() route above and handle your routes, like /a, /b, etc.
Or use a catch-all route:
#app.route("/{full_path:path}")
async def catch_all(request: Request, full_path: str):
print("full_path: "+full_path)
return templates.TemplateResponse("index.html", {"request": request})
The "traditional" approach to running a web application is to have a server that serves your web application (i.e. your React app). Usually you'll hear about nginx being used as the web server being used for modern day single page applications. When you run npm run start you start up a local server on your machine and it makes your app available at http://localhost:8080 (the port and hostname are of course configurable).
When it comes to your API, it should be it's own server available at a different endpoint/url, and then your web app will make API calls to that endpoint/url in order to fetch data.
The way you're describing things, it sounds like you're trying to use FastAPI to server render your web app, but I'm not sure how feasible that is, especially considering there is an entire framework solely dedicated to server rendering react applications.
I've also struggled with this and here's an approach that worked for me
import logging
from fastapi import FastAPI
from starlette.responses import RedirectResponse
from starlette.staticfiles import StaticFiles
app = FastAPI()
#app.get("/")
async def index():
return RedirectResponse(url="/index.html")
app.mount("/", StaticFiles(directory="backend/ui/"), name="ui")
Note: Please observe that app.mount is called after registering the / route. From my experience if the mount is called before the registration then it will simply not redirect to index.html
Note: I use react-scripts to generate the app.
Dear hainabaraka
Your question resembles this one: How do I serve a React-built front-end on a FastAPI backend?. In that one, I contributed an answer, but I'd like to also refer you to Mike Chaliy's answer, which updates mine.
In any case, here are two thoughts on that solution (that I should really update) and the answers you get here:
the nginx approach: this removes responsibility from your code, meaning that it also removes control from you. DevOps love this kind of "you do your thing and let me worry about that" approach, but let's just say that this is a good solution... not for your case. You want to serve from your API.
By the way, "it should be it's own server" has no apostrophe!
the Jinja2 approach: I'm not sure this would work, and even if it did, it would be introdsucing a lot of CPU waste. Jinja2 is an excellent tool for Python based backend tremplate rendering. I used it extensively to generate HTML medical reports to be then PDF-rendered but in this case it always sounds like a "Yes, it works, but...". Rule of thumb for "but"-sentences: everything to the left of the "but" is irrelevant.
the FastAPI RTFM approach: I am a HUGE fan of FastAPI and I'm (extremely slowly) trasnslating its documentation to European Portuguese, but the examples there are very very limited. Referring you to the FastAPI docs is assuming you're an idiot that never thought of that.
other approaches: I saw a bungh of these that, while well intentioned, did not really work because they were either produced by that kinf of people here in SO that don't really test their answer before answering, or by pure back-end devs that have no clue how a React (or a SPA) app works. Some can even serve a home page but then routing kills it.
The solution I present works and has been working for me for years now, both with Vue and React SPAs. The caveat is that you either serve your app from a special endpoint (I suggest /my-spa, which is quite lame), or, if you want the app to come from /, you have to do the
app.mount('/', SPAStaticFiles(directory='folder', html=True), name='whatever')
after all other endpoints, and you cannot obviously have other endpoints conflicting with either / or any React route within it. This perhaps adds to why APIs are recommended to hang from an /api endpoints, and possibly versioned, like /api/v1/.... Please let me know if this works for you.
For that, there an excellent resource in Zalando RESTful API and Event Guidelines.
So I have a crud applicatio here this is the link
https://crud-application-x.herokuapp.com/getstudents
my boss was telling me this
Add one record that I can see when I visit the url.
what does it mean by adding a record on a crud app. Does it mean adding new data
I think the issue here is not related to a misunderstanding, but that you're both looking at different things. You're probably testing it at your development environment only and everything works as expected. Your boss, on the other hand, is using the app through the URL you've provided and is unable to create a new student.
The issue here is that you are not using the right address to access your API in production, so the student is never created, take a look:
The address http://localhost:3200/... will only work on your development environment. Once axios can't reach the server, adding a new student throws an Error: Network Error.
In order to fix this, you'll have to start using the right URL for each environment. The easiest way to do so, in my opinion, is through environment variables.
How to set up an environment variable
As it looks like you're using create-react-app, this resource will help you set them up as needed. As a simple example, you can create the following two files at your app root directory:
.env.development
REACT_APP_API_PATH=http://localhost:3200
.env.production
REACT_APP_API_PATH=https://crud-application-x.herokuapp.com
Now you can easily use the right URL for each environment:
axios.post(`${process.env.REACT_APP_API_PATH}/students/addStudent`)
What's the best practices to hide or prevent the user see the credentials (implemented in WebService calls). The development is ReactJS and use Heroku to deploy the WebApp.
I have this code:
I want to prevent the user can see the credentials and some security details.
I started using the node module dotenv recently and really like how easy it is to use. All you need to do is install it and create a .env file with your environment variables like this:
.env
SECRET_KEY=123456
ANOTHER_KEY=78901
Then, require it as early as possible in your application:
require('dotenv').config().
I do this inside my server.js file (or whatever you name it).
That's it! Anything stored in the file can now be accessed by doing process.env.{name}
For example:
let secret = process.env.SECRET_KEY;
console.log(secret); // 123456
This is not really possible to do in a client side because all the HTTP calls can be easily visible in Network tab in Chrome Inspect Elements(or any web browser).
I would suggest you work on the security so you don't care if a user will see your HTTP endpoints or not.
You can also consider making your HTTP request on a server which will act as a bridge between your client and an API.
I would like to accesss the sitecore DB and items from console application like
Sitecore.Data.Database db = Sitecore.Context.Database
or
Sitecore.Data.Database db = Sitecore.Data.Database.GetDatabase("master")
how do I configure and setup my console application to access the DB as above?
Thanks Everyone for the suggestion, I am really interested in config changes, I used webservice, but it has very limited methods. For example, if I would like create an Item with the template and insert the item with prepopulated value, there is no such option. The reason I am looking for the console apporach is I would like to import the contents from XML or excel sheet and push those to the sitecore tree, eventually use the scheduled task to run the console app periodically. I do not want to copy the entire web.config and app_config. If anyone has already done this, could you please post your steps and necessary config changes?
You have two options I think:
1) Import the Sitecore bits of a website's web.config into your console application's app.config, so that the Sitecore API "just works"
I'm sure I read a blog post about this, but I can't find the reference right now. (I will have another look) But I think the simple but long winded approach is to copy all of the <sitecore/> element and all the separate files it references. I'm fairly sure you can whittle this down to a subset of the config required for data access with a bit of thinking.
2) Don't use the Sitecore API directly, connect to a web service that exposes access to it remotely.
There are a few of these that already exist. Sitecore itself exposes one, Sitecore Rocks has one, and Hedgehog TDS has one too. And you can always write your own (since any web service running inside the Sitecore ASP.Net app can make database calls and report values back and forth - just remember to consider security if this web service might end up exposed externally for any reason)
John West links to some relevant stuff here:
http://www.sitecore.net/Learn/Blogs/Technical-Blogs/John-West-Sitecore-Blog/Posts/2013/09/Getting-Data-Out-of-the-Sitecore-ASPNET-CMS.aspx
-- Edited to add --
I've not found the blog post I remember. But I came across this SO thread:
Accessing Sitecore API from a CLI tool
which refers to this blog post:
http://www.experimentsincode.com/?p=232
which I think gives the info you'll need for option 1.
(And it reminds me that, of course, when you copy the config stuff you have to copy the Sitecore binaries into your app's folder as well)
I would just like to expand on #JermDavis' post and note that Sitecore isn't a big fan of being accessed when not in a web application. However, if you still want to do this, you will need to make sure that you have all of the necessary configuration settings from the web.config and App_Config of your site in your console application's app.config file.
Moreover, you will never be able to call Sitecore.Context in a console application, as the Sitecore Context sits on top of the HttpContext which means that it must be an application and have a valid request for you to use it. What you are looking for is something more along the lines of Sitecore.Configuration.Factory.GetDatabase("master").
Good luck and happy coding :)
This sounds like a job for the Sitecore Item Web API. I use the Sitecore Item Web API whenever I need to access Sitecore data from the master database outside the context of the Content Management server or outside of the context of the Sitecore application. The Web API definitely does not allow you to do everything that the standard Sitecore API does but it can act as a good base and I now extend upon the Web API instead of writing my own custom web services whenever possible.
Thanks to JemDavis's advise.
After I copied the configuration and made changes to config section to get rid of conflicts. I copied almost all of Sitrecore, analytics and lucene dlls, it worked great.
Only thing you have to remember is, copy the app_config folder to the same location where your dlls are.
Thanks again JemDavis....