I wrote a structure like display in the tree below.
.
├── README.md
├── db
│ └── db.go
├── go.mod
├── go.sum
├── handler
│ ├── category.go
│ ├── handler.go
│ └── users.go
├── main.go
├── model
│ ├── category.go
│ ├── model.go
│ └── users.go
└── route
├── category.go // init() ❌ error to using package vars
├── route.go // init() writing package vars
└── users.go // init() ✅ no error to using package vars
All the files in the packages except the one with the same name (route/route.go, handler/handler.go,...) are generated automatically. For these files to extend the package variables, I use golang's func init(){} ex:
route/route.go
package route
import (
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)
var (
// public routes
e *echo.Echo = echo.New()
// restricted routes
r *echo.Group = e.Group("/restricted")
)
func init() {
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"http://localhost:3000"},
AllowMethods: []string{echo.GET, echo.PUT, echo.POST, echo.DELETE, echo.OPTIONS},
AllowHeaders: []string{echo.HeaderAuthorization, echo.HeaderContentType},
}))
e.Use(middleware.Recover())
r.Use(middleware.JWT([]byte("secret")))
}
route/category.go
package route
import (
"github.com/username/project/handler"
)
func init() {
r.GET("/category", handler.ListCategory)
r.POST("/category/add", handler.CreateCategory)
r.GET("/category/:id", handler.ReadCategory)
r.PUT("/category/edit/:id", handler.UpdateCategory)
r.DELETE("/category/:id", handler.DeleteCategory)
}
route/user.go
package route
import (
"github.com/username/project/handler"
)
func init() {
r.GET("/users", handler.ListUsers)
r.POST("/users/add", handler.CreateUser)
r.PUT("/users/edit/:id", handler.UpdateUser)
r.DELETE("/users/:id", handler.DeleteUser)
e.POST("/auth", handler.Login)
e.POST("/lost", handler.Lost)
e.POST("/password", handler.Password)
}
As you already understood, the category.go init() starts before the router.go init(), which is described here: Go Package initialization.
After coding a pretty program that auto writes routes like route/category.go. I realize that to solve this problem, I will have to rename router/router.go to router/0router.go (it works) so that it is still at the top of the pillar, but it's not a good approach.
Have any suggestions for this tree and the use of golang ini() ?
Thank you
Use variable declaration expressions to avoid file name dependencies. The assignments execute before the init() functions that reference the variables.
var (
// public routes
e *echo.Echo = newPublic()
// restricted routes
r *echo.Group = newRestricted()
)
func newPublic() *echo.Echo {
e := echo.New()
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"http://localhost:3000"},
AllowMethods: []string{echo.GET, echo.PUT, echo.POST, echo.DELETE, echo.OPTIONS},
AllowHeaders: []string{echo.HeaderAuthorization, echo.HeaderContentType},
}))
e.Use(middleware.Recover())
}
func newRestricted() *echo.Group {
r := e.Group("/restricted")
r.Use(middleware.JWT([]byte("secret")))
return r
}
Related
I just made changes to the application structure for my Laravel application. It works well when runnning tests (for the Http controllers). The problem is when i try to run artisan commands (that literally need to access "getNamespace()" method), it wont resolve the namespaces.
Here are the composer.json:
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/",
"Modules\\": "modules/"
},
"files": [
"app/Helpers/app.php",
"app/Helpers/form.php",
"app/Helpers/view.php"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
I do aware that i can add Modules\ModuleA, Modules\ModuleB to the composer json, but that put alot of work. So i decided to override the getNamespace() method instead, but what is the best way to override single method illuminate/foundation/xxx classes through service provider?
Folder tree:
laravel-project/
├── app/
│ ├── Exception
│ ├── Providers
│ └── ...
├── modules/
│ ├── ModuleA/
│ │ ├── Services
│ │ ├── Http/
│ │ │ ├── Controllers
│ │ │ └── Requests
│ │ └── Models
│ └── ModuleB/
│ └── ...
├── tests
└── ...
If you want to override a single method in Illuminate\Foundation\Application through a service provider in Laravel, you can use the following steps:
Create a new service provider by running the command php artisan make:provider YourServiceProvider in your terminal.
In your YourServiceProvider class, extend the Illuminate\Support\ServiceProvider class.
Override the register() method in your YourServiceProvider class. In this method, you can bind your custom implementation of the method you want to override to the container. For example, if you want to override the loadEnvironmentFrom() method, you can do so as follows:
use Illuminate\Foundation\Application;
class YourServiceProvider extends ServiceProvider
{
public function register(){
$this->app->bind(Application::class, function ($app) {
return new class($app) extends Application {
public function loadEnvironmentFrom($file)
{
// Your custom implementation here
}
};
});
}
}
Then in your config.app file, add the service provider to the list of providers:
'providers' => [
// Other service providers
App\Providers\YourServiceProvider::class,
],
This way, the method you've overridden will use your custom implementation instead of the default implementation in Illuminate\Foundation\Application.
Hope this helps
I am trying to create a navbar using react-router-bootstrap but keep getting an invalid hooks error when I try to use the LinkContainer. Not having used react-router-bootstrap before, I wrote a quick test app:
Here is my App.js:
import * as React from "react";
import { Routes, Route } from "react-router-dom";
import TestChart from './components/TestChart';
import Header from "./components/Header";
import Home from './components/Home';
// import './global.css';
function App() {
return (
<div className="App">
<h1>Test!</h1>
<Header />
<Routes>
<Route path="/" element={<Home />} />
<Route path="TestChart" element={<TestChart />} />
</Routes>
</div>
);
}
export default App;
Hear is my Navbar/Header component:
import React from "react";
import {Navbar, Nav} from 'react-bootstrap';
import { LinkContainer } from "react-router-bootstrap";
const Header = () => {
return (
<Navbar bg="light" expand="lg">
<h1>Test Navbar</h1>
<Navbar.Brand>My Chart App</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">
<LinkContainer to="/TestChart">
<Nav.Link>Test Chart</Nav.Link >
</LinkContainer>
</Nav>
</Navbar.Collapse>
</Navbar>
)
}
export default Header;
I have the following installed in the project:
├── #reduxjs/toolkit#1.6.2
├── #testing-library/jest-dom#5.15.0
├── #testing-library/react#11.2.7
├── #testing-library/user-event#12.8.3
├── bindings#1.5.0 extraneous
├── bootstrap#5.1.3
├── chart.js#3.6.1
├── chartjs#0.3.24
├── file-uri-to-path#1.0.0 extraneous
├── history#5.1.0
├── nan#2.15.0 extraneous
├── react-bootstrap#2.0.3
├── react-chartjs-2#4.0.0
├── react-dom#17.0.2
├── react-redux#7.2.6
├── react-router-bootstrap#0.26.0
├── react-router-dom#6.0.2
├── react-router#6.0.2
├── react-scripts#4.0.3
├── react#17.0.2
└── web-vitals#1.1.2
Whenever I coment out the LinkContainer, the app compiles and renders in the browser. I have no idea why it's throwing a invalid hooks error when I use the LinkContainer.
I am building my first GraphQL based project so forgive me if this is a newbie question. I have arranged my queries and mutations in the following fashion:
├── graphql
│ ├── lessons
│ │ ├── logic.js
│ │ ├── query.js
│ │ ├── schema.js
│ │ └── types.js
│ ├── schema.js
│ └── users
│ ├── logic.js
│ ├── mutation.js
│ ├── query.js
│ ├── schema.js
│ └── types.js
This is my users/query.js file:
const graphql = require('graphql')
const types = require('./types.js')
const logic = require('./logic.js')
module.exports = new graphql.GraphQLObjectType({
name: 'UserQuery',
fields: {
user: {
type: types.userType,
args: {
email: { type: new graphql.GraphQLNonNull(graphql.GraphQLString) }
},
resolve: (root, { email }, context) => logic.getUser(email, context)
}
}
})
In my schema.js, I have combined the queries of users and lessons as per the following code:
module.exports = new graphql.GraphQLSchema({
query: new graphql.GraphQLObjectType({
name: 'RootQuery',
fields: {
lessons: { type: require('./lessons/query.js') },
users: { type: require('./users/query.js') }
}
})
})
Now the problem is, the following query:
{
users {
user(email: "a#.a") {
name,
purchases
}
}
}
is producing the following output:
{
"data": {
"users": null
}
}
I am getting a null in place of a user record. What am I doing wrong here?
My problem
My apologies if the problem is trivial - I'm fairly new to golang, and want to understand the imports mechanism. I use OSX and simple go programs compile and work well.
I've generated a golang server using automatic code generator in the swagger editor. I've unzipped the code into some directory in /tmp/, and the resulting server contains the following main.go file:
package main
import (
// WARNING!
// Change this to a fully-qualified import path
// once you place this file into your project.
// For example,
//
// sw "github.com/myname/myrepo/go"
//
sw "./go"
"log"
"net/http"
)
func main() {
log.Printf("Server started")
router := sw.NewRouter()
log.Fatal(http.ListenAndServe(":8080", router))
}
As expected from the comments, go build main.go Fails with the following error:
main.go:11:2:
go/default.go:3:1: expected 'IDENT', found 'import'
Forensics
The directory tree of the project
/tmp/goserver/go-server-server
├── LICENSE
├── api
│ └── swagger.yaml
├── go
│ ├── README.md
│ ├── app.yaml
│ ├── default.go
│ ├── logger.go
│ └── routers.go
└── main.go
go/default.go
package
import (
"net/http"
)
type Default struct {
}
func QuestionimagePost(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
}
What have I tried
Read about go packages
Tried to understand the package / import relationship in some github projects
Moved the directory tree to $GOPATH/src, and changed the import to sw "sw/go-server-server/go", which still gives main.go:13:2:
go/default.go:3:1: expected 'IDENT', found 'import'
What should be the fully-qualified import path of the sw import, and what does it mean?
The following did the trick:
Adding a package name to all .go files in the go folder (I used blah)
eg. in go/routers.go
package blah
import (
"log"
"net/http"
"time"
)
func Logger(inner http.Handler, name string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
inner.ServeHTTP(w, r)
log.Printf(
"%s %s %s %s",
r.Method,
r.RequestURI,
name,
time.Since(start),
)
})
}
Do the same for go/logger.go and, in your case, default.go
Following an go/routers.go:7:2: cannot find package "github.com/gorilla/mux" error, go get 'github.com/gorilla/mux'
You need to export some path as the GOPATH, say $HOME/go.
export GOPATH=$HOME/go.
Then you can put your project in $GOPATH/src/go-server-server ($HOME/go/src/go-server-server) and your fully qualified path would be go-server-server/go if I am reading everything correctly.
I'm trying to follow the section in the Django docs called Managing static files. I am interested in finding out:
What I am doing wrong.
Or, what is wrong with the Django docs.
1) Make sure that django.contrib.staticfiles is included in your INSTALLED_APPS.
In the default settings.py file:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles', #<****HERE*****
)
2) In your settings file, define STATIC_URL, for example: STATIC_URL = '/static/'
In the default settings.py:
STATIC_URL = '/static/'
3) In your templates, either hardcode the url like /static/my_app/myexample.jpg
In mysite2/mysite2/views.py:
from django.http import HttpResponse
def index(request):
return HttpResponse('''
<h2>Hello</h2>
<img src="/static/mysite2/Aerial03.jpg">
''')
4) Store your static files in a folder called static in your app. For example: my_app/static/my_app/myimage.jpg.
Here is my directory structure:
(django186p34)~/django_projects$ tree mysite2
mysite2
├── db.sqlite3
├── manage.py
└── mysite2
├── __init__.py
├── settings.py
├── static #<****HERE*****
│ └── mysite2
│ └── Aerial03.jpg
├── urls.py
├── views.py
└── wsgi.py
4 directories, 13 files
But after starting the server:
(django186p34)~/django_projects/mysite2$ python manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
November 26, 2015 - 02:44:57
Django version 1.8.6, using settings 'mysite2.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
And then navigating in my browser to:
http://localhost:8000/
I see the text:
Hello
but the image is not found:
[Error] Failed to load resource: the server responded with a status of 404 http://localhost:8000/static/mysite2/Aerial03.jpg
I've tried many combinations of urls in my html and nothing works.
Here is settings.py in its entirety(I made no changes):
"""
Django settings for mysite2 project.
Generated by 'django-admin startproject' using Django 1.8.6.
For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'pmaup3%)m09cs2goldduw2iogso%(#8cz0s-zmr%*e'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
)
ROOT_URLCONF = 'mysite2.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'mysite2.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/
STATIC_URL = '/static/'
This fixed things:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'mysite2', #<*****HERE*****
)
And if you organize things so that you have apps inside your project, e.g.:
(django186p34)~/django_projects$ tree mysite3
mysite3
├── db.sqlite3
├── manage.py
├── myapp
│ ├── __init__.py
│ ├── admin.py
│ ├── migrations
│ │
│ │
│ ├── models.py
│ ├── static
│ │ └── myapp
│ │ └── Aerial03.jpg
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── mysite3
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
8 directories, 24 files
Then in settings.py add your app name to INSTALLED_APPS:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp', #<*****HERE*****
)
Everything else in the default settings.py stays the same. However, the urls are different:
mysite3/mysite3/urls.py:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^myapp/', include('myapp.urls')),
]
mysite3/myapp/urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
]
And in your browser, the url becomes:
http://localhost:8000/myapp/
myapp/views.py:
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
def index(request):
return HttpResponse('''
<h2>Hello</h2>
<img src="/static/myapp/Aerial03.jpg">
''')