Intro
I’m working with my son to build a system to manage all sorts of data, files and devices. Our apps will need to run on OSX, Windows, Linux, and possibly Raspberry Pi machines. In addition to multiple platform support, our apps need to be fast, we will eventually be working with near real time data. So I started looking for a language that would fit the bill and Go caught my eye. Why? For one, it compiles, I mean it really compiles down to an actual executable, not byte code. Another reason is some of the speed benchmarks I saw said go was second only to C for speed. Also, if I can’t get Go to be fast enough I can load C libraries too. Lastly, Go appears to have a vibrate third party package ecosystem. So I thought I’d give Go a try. Since I most of my day job work is in web development I thought I’d learn Go while I build out a web service and share my experience with others who may be curious about Go.
Goal
In this post we will start building out a API to manage attributes. Every resource in our system will have attributes and these attributes will be different per each type of resource. The API will provide the necessary functionality to assign,remove and list attributes the available attributes assigned to a particular resource. In this post we will set up the Go development environment and create the basics for the GET /attributes/:resource.
Setup
Installing and Configuring Go
Installing Go is pretty straight forward, just follow the instructions on golang.org’s install page. To ensure Go is setup correctly in your development environment run go version
and you should see output similar to this, go version go1.1.2 darwin/386
After installing Go I need to do a few tasks to setup my Go work space. The Go tools are created to work with a certain directory structure, mainly a ‘home’ directory that contains three subdirectories: src, where my source files will go; pkg, where any of 3rd party packages I install will live; and bin, where any executables I install will live. the directories have been created with in the ‘home’ directory a GOPATH environment variable should be set to that directory. In my environment my $GOPATH
variable is set to ~/src/go
. For a more detailed overview of the workspace layout read the “How to Write Go Code” page on the golang.org site.
Editor Setup
I use emacs to write the vast majority of my code. I would imagine that my editor choice is not the norm for most of you reading this post so I’m going to add a few other editors that have Go support.
Eclipse | goclipse |
Emacs | go-mode.el |
Sublime | go plugin |
Vim | go language vim support |
Follow the instructions and your editing environment will be ready to ‘Go’.
Installing Third Party Packages
The last step before we start writing code is to install the lone third-party package that will use to create the attributes API. Go makes it easy to install the packages by providing the go get tool. As you can see below you just add the package you wish to install after go get. When the install completes the package can be found by running ls $GOPATH/pkg
in a terminal window.
go get github.com/codegangsta/martini
Now that I have Go installed, my work environment setup including my editor, installed martini, I’m ready to start coding. I will be writing the code for this blog series in the $GOPATH/src/github.com/rippinrobr/martini-to-go-posts
directory.
Writing the Code
A Basic HTTP Server
One of the reasons why I chose to get familiar with Martini is it allows you to get a functional web server up and running with about 10 lines of code. So to make sure I have everything in place and I can respond to an HTTP GET / request I’m going to start with a very basic app. This app will respond to the HTTP GET / request by returning a string that reads "Where are the attributes?!?!” Here’s the code
package main
// loading in the Martini package
import "github.com/codegangsta/martini"
func main() {
// if you are new to Go the := is a short variable declaration
m := martini.Classic()
// the func() call is creating an anonymous function that retuns a stringa
m.Get("/", func() string {
return "Where are the attributes?!?!"
})
m.Run()
}
Before you run it let’s go over the code. The first line defines the main package, all Go code must be in a package. This code belongs to the main package which is a special package in Go. The main package is where the main function must be for all executable Go projects. Once I’ve defined the package I need to let go know what packages I want to import. In this code I am only importing the the martini package. This statement makes the martini functions, structs, and interfaces available to my code. To call anything in this package I need to preface the call with martini
. In this example I’m only using one function from martini, martini.Classic()
.
The martini.Classic()
call creates the classic martini object that I will use to declare the supported routes and start the service. This particular line makes use of the ‘short variable declaration’ syntax. The := determines the type of the object, var, etc.. on the right side and creates a variable of that type on the left side of things. The := syntax can only be used within the body of a function.
Now that I have created my martini object I can start setting up to handle our HTTP GET / request. Adding a route is to handle is pretty straight forward. For this simple example I declare the route I want to respond to “/“ and I am using an anonymous function to handle the requests. If you are new to Go the string that follows func() is the return value of the function.
m.Get( “/”, func() string {
return “Where are the attributes?!?!”
})
Since this is the only route I’ve declared any other route sent to the service will result in a 404 error. The last bit of code is the Run() call which starts the HTTP server. By default the server will listen on port 3000, if you want to change that port set the PORT environment variable to the new value and restart the server. Martini automatically looks for the PORT variable.
The next step is to actually see the code in action. The easiest way to do that is by calling go run.
go run attr-server.go
The go run command will compile and run the application. If there are no errors you should see a message [martini] listening on host:port :8000
. My server is running on port 8000 because I've set my PORT environment variable to 8000.
Now, to make sure that the response is what I expect. I'm going to run:
curl http://localhost:8000/
And I should see should see Where are the attributes?!?!
string returned. As you can see it is pretty simple to get a basic HTTP server up and running.
GET /attributes/:resource
Ok, now that I’ve shown you the basics of martini its time to build out our first ‘real’ route. Remember, the goal of this service is to track a resource’s attributes. Resources can be anything from a TV, scoreboard, ad boards, etc.. Each of these will have its own set of attributes. For this blog post the /attributes/:resource route need to do the following:
- If the resource requested is a TV then we will return a JSON object with all the attributes assigned to a TV and the HTTP Status code of 200
- If the resource is not a TV then we will return a JSON error object that we will define and a status code of 404.
New Packages
I am going to need to include a few more packages to the code to meet my needs. The first import is the net/http
package. I’m importing this package so I can use http.StatusOK
instead of the number 200, it will make the code a little more readable. The next new package is the strings
package. I’m using this package so I can convert the requested resource to lower case so that I can ensure my string comparison is comparing the input in the same case as my test string.
import (
“net/http” // this will allow us to use http.StatusOK and http.StatusNotFound instead of 200 and 404
“strings” // I’m adding this so I can ensure that we are comparing lower case strings.
“github.com/codegangsta/martini”
)
Notice that the import call has changed. When there are multiple packages to import you can group them together as I have above or you could use an import call for each one. Either way works but I believe the way I have it here is the more idiomatic Go way.
The New GET Handler
The next change is that I’ve replaced the m.Get call we had previously with this one:
m.Get("/attributes/:resource", func( params martini.Params ) (int, string) {
resource := strings.ToLower( params["resource"] )
if resource == "tv" {
return http.StatusOK, “a TV attributes object will be returned here"
} else {
return http.StatusNotFound, "JSON Object here"
}
})
The new m.Get call has a bunch of new parts to it. The first /attributes/:resource
tells martini what route to look for. The :resource is used to indicate to martini that whatever value is here we want to store in params map. The value will be stored under the key ‘resource’, notice that the key does not have the leading colon. This handler’s function has one parameter, params, which will contain all route parameters. Next is the return value declaration. This version of the handler returns two values, the HTTP Status code and a string.
The guts of the function are there to determine if the resource being requested is a TV or not. If it is return OK if not return a not found error. Right now the code has placeholders in it but soon the strings will be string representations of a JSON object. If you are new to Go like me the if
statement looks a little naked, there are no () around the test portion. The return statements are a little different than what I’m used to seeing also. Remember that this function has two return values and on the return lines the values are separated by a comma.
Now that we’ve talked it to death if you want to see it an action download the code form here https://gist.github.com/rippinrobr/9084362 and run it using:
go run attr-server.go
In a seperate terminal run the following curl command and you should see similar output.
curl -v http://localhost:3000/attributes/tvs
* Adding handle: conn: 0x7f911c004400
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7f911c004400) send_pipe: 1, recv_pipe: 0
* About to connect() to localhost port 3000 (#0)
* Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET /attributes/tvs HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:3000
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Content-Type: text/plain; charset=utf-8
< Content-Length: 16
< Date: Wed, 19 Feb 2014 01:27:00 GMT
<
* Connection #0 to host localhost left intact
JSON Object here
The curl -v
displayed enough output so that you can see just about everything that happened during the request. I’m using it here so you can see that the call above does in fact return a 404 code in addition to the error message. To see what happens when you pass it TV rerun the command after removing the trailing s from tvs. The HTTP/1.1 status should now be 200.
Sending the JSON Object
Now that I have the basic logic in place its time to start building out the infrastructure to support resource attributes. To help model the resource to attributes relationship I am introducing two new structs, Attribute and ResourceAttributes.
type Attribute struct {
Name string `json:"name"`
DataType string `json:"type"`
Description string `json:"description"`
Required bool `json:"required"`
}
type ResourceAttributes struct {
ResourceName string `json: "resourceName"`
Attributes []Attribute `json: "attributes"`
}
The Attribute struct contains all of the information I want to store about each attribute. The ResourceAttribute struct is used to represent the relationship between a resource and its attributes. Since these structs will be converted to JSON and I want to the names of the field to follow proper JSON naming conventions I’m using the “field's tag value” to convert the names to lower case during the JSON conversion process.
The updated handler will be returning a string representation of the JSON object and in order to do that I need to create a String method for each of the types I’ve declared. I want to send all of my structs back to the client as JSON objects I need to create two String() methods. The method below is used on the ResourceAttributes struct.
func (ra ResourceAttributes) String() (s string) {
jsonObj, err := json.Marshal(ra)
if err != nil {
s = ""
} else {
s = string( jsonObj )
}
return
}
There are two differences in the declaration of this method from the functions I declared earlier. The first is right after the func
keyword is what looks like a parameter declaration. What it does is declare what type is the 'receiver' for this method. What that means is any ResourdeAttribute object can call the String()
method. The second difference is in the way the return value is declared. This method makes use of Go's named return value. What that means is whatever the value of the variable s
is at the time that the method returns will be the value returned by the method.
First, the method converts the receiver into JSON. If there are no errors returned during the conversion process then the JSON representation is converted to a string and stored in s
. If an error occurs then s is set to an empty string.
To be able to send all of the structs I declared as JSON I would have to create a String()
method for each type. The methods would be exactly the same except for the reciever. Not exactly keeping the code DRY. Thankfully shortly after writing the code of this part of the blog I reached a section on interfaces in The Go Programming Language Phrasebook and I was happy to see that using
interfaces will let me DRY up the String() methods.
A Go interface is a set of methods. Any struct that has all of the methods in the interface declaration is said to implement the interface. Interfaces can have 1, 10, or no methods. So I decided to try an empty interface declaration that would stay within my main package.
type jsonConvertible interface { }
Since the name of this type starts with a lower case character it is only visible within the package it was declared in. Now any struct I declare in the main
package will implement the jsonConvertible interface. After creating the interface I moved away from using methods back to a normal function, I created a new function named JsonString. JsonString has a single parameter, a jsonConvertable struct. Now I can have one function to convert all my structs into a JSON string.
func JsonString( obj jsonConvertible ) (s string) { jsonObj, err := json.Marshal( obj )
if err != nil {
s = ""
} else {
s = string( jsonObj )
}
return
}
If you want to see this version of the code in action you can grab it in this gist and go run
it.
Setting the Content-type to application/json
When you run the latest and greatest you see that the server does send back a JSON string but if you look at the headers you can see that the Content-Type is set to text/plain. I want the Content-Type to be application/json. In order to do that I need to set the Content-Type before I send the response. Luckily, using martini makes this as easy as adding a new parameter to my handler function, writer http.ResponseWriter. I can use the new parameter to set the correct Content-Type.
writer.Header().Set("Content-Type", "application/json")
Now whichever object is returned, it will have the correct Content-Type set. To see for yourself, clone the repository, checkout the 1st-post branch and run it. You’ll see in the headers that I now have the correct Content-Type set.
Summary
With that, I’ve completed everything that I set out to do by the end of this post. I showed you where to get Go and how to setup your environment. I’ve walked you through how to create structs, respond to HTTP GET calls and how to return a JSON string. In addition to that I introduced you to interfaces in Go.
In my next post, I will add CRUD functionality using MongoDB, showing you how to add middleware to pass along database connectivity to the request handlers. By the end of the second post the attr-server will retrieve all available attributes assigned to a TV from the database using our /attributes/:resource route.
Resourcs
Editors
Eclipse | goclipse |
Emacs | go-mode.el |
Sublime | go plugin |
Vim | go language vim support |
Go Language
GitHub & Gits
- My Github project - each post will have its own branch with the master branch being the latest and greatest.
- Where are the attributes
- The New GET Handler
- The DRY Conversion
Blogs & Books
jika anda belum mempunyai kemampuan yang mumpuni. Jangan selalu bergantung dengan kartu susunan besar Jika anda selalu memperoleh kartu dengan susunan bagus,
ReplyDeleteasikqq
dewaqq
sumoqq
interqq
pionpoker
bandar ceme terpercaya
hobiqq
paito warna terlengkap
bocoran sgp
Best Article BUY ADDERALL ONLINE Excellent post. I appreciate this site. Stick with it! Because the admin of this web page is working, no doubt very quickly it will be well-known, due to its quality contents.This website was how do you say it? Relevant!! Finally, I’ve found something that helped me.
ReplyDeletebuy heroin online
ReplyDeletebuy alprazolam powder online
buy cocaine online
buy mephedrone online
buy 3meo pcp online
buy xenax online
buy pills online
buy fentanyl powder online
buy scopolamine powder online
buy vyvanse powder online
buy coke powder online
buy research powder online
https://www.buyweedcenter.com/product/tahoe-og-cannabis-oil/
ReplyDeleteVyvanse Products Online.
ReplyDeleteLipitor Online.
LSD Online.
Tahoe OG Cannabis Oil.
ReplyDeletebuy humalog kwikpen online
ReplyDeletebuy lantus solostar pen online
buy novolog flextouch pens online
buy basaglar kwikpen online
buy apidra solostar pens online
buy apidra insulin vail online
buy ozempic online
buy saxenda online
buy Toujeo solostar pen online
buy victoza online
buy trulicity online
buy adipex-p online
buy belviq online
buy orlistat online
buy meridia online
buy contrave online
buy insuline online
buy humalog kwikpen online
ReplyDeletebuy lantus solostar pen online
buy novolog flextouch pens online
buy basaglar kwikpen online
buy apidra solostar pens online
buy apidra insulin vail online
buy ozempic online
buy saxenda online
buy Toujeo solostar pen online
buy victoza online
buy trulicity online
buy adipex-p online
buy belviq online
buy orlistat online
buy meridia online
buy contrave online
buy insuline online
ReplyDeleteHello, have you checked our farm?we own and train the best babies that will do just fine in a new home
Maine coon kittens
Maine coon kittens for sale
Maine coon kittens for adoption
Munchkin kittens for adoption
Munchkin kittens for sale
Siamese kittens for sale
Siamese kittens
Siamese kittens for adoption
Ragdoll kittens for adoption
sphynx kittens for adoption
Tibetan mastiff puppies for adoption
Tibetan mastiff puppies for sale
carolina dogs for sale
carolina dogs for adoption
catahoula leopard dogs for adoption
catahoula leopard dogs for sale
swedish vallhunds for sale
swedish vallhunds for adoption
Thank you
We are a fully licensed, Limits & Liability Corporation dedicated to raising happy and healthy exotic birds. Species we raise include Bare Eye Cockatoos, Black Palm Cockatoos, Citron Crested Cockatoos, Ducorp Cockatoos, Eleanora Cockatoos, Goffin Cockatoos, Greater Sulpher Crested Cockatoos, Lesser Sulpher Crested Cockatoos, Major Mitchell Cockatoos, Moluccan Cockatoos, Red-Tailed Black Cockatoos, Rose Breasted Cockatoos, Umbrella Cockatoos. All of our baby Cockatoos are abundance weaned, allowed to fully fledge, and are well socialized with other birds and humans. We offer a guarantee on the health of our babies.
ReplyDeleteVisit our site for more info
munchkin cat for sale
munchkin kittens for sale
munchkin kittens
munchkin kitten
Dank vapes Cartridges
Dank vapes
Cockatoos for Sale
Umbrella Cockatoos for Sale
Bare Eye Cockatoos for Sale
Black Palm Cockatoos for Sale
Citron Crested Cockatoos for Sale
Cockatoos for sale
Red Tailed Black Cockatoos for Sale
Rose Breasted Cockatoos for Sale
Sulpher Crested Cockatoos for Sale
Dank Catridges
Dank vapes
dank vape flavors
Dank vapes
I have to search sites with relevant information on given topic and provide them to teacher our opinion and the article.
ReplyDelete360Digitmg Data-science training in chennai
If your looking for Online Illinois license plate sticker renewals then you have need to come to the right place.We offer the fastest Illinois license plate sticker renewals in the state.
ReplyDelete360Digitmg financial analytics training in hyderabad
ReplyDeletebuy weed online at Legit Weed Store
order your cannabis now at Order Cannabis Meds
Buy marijuana online at 420 Delivery Store
Buy medical cannabis online at at Canna Med Shop
Get your Pill refills at Pill Pharma
dimethyltryptamine-dmt
ReplyDeletemagic-mushrooms
valium-10mg
adderall-amphetamine
lsd-lysergic-acid-diethylamide
alpha-pvp-crystal
codeine-linctus-syrupcare-plus
phenergan-elixir-5mg-5ml-promethazine-sugar-free-oral-solution-100ml
buy cough syrup
buy codeine linctus
buy care plus
phenergan-elixir
phenergan-elixir
phenergan
buy phenergan-elixir
buy lean
lean for sale
buy lean online
lean
buy promethazine oral solution online
promethazine for cough
what is promethazine
buy cough syrup online
promethazine and codeine
buy Hi tech lean online
hi tech promethazine and codeine oral solution
wockhardt promethazine for sale
buy wockhardt codeine online
Akorn promethazine for sale
buy Tris promethazine plain online
tris promethazine for sale
promethazine and codeine oral solution
purple drank for sale
buy purple drank online
Actavis lean
buy actavis promethazine online
buy lagal lean online
legal lean for sale
what is leagal lean
buy drug free syrup in USA
buy official lean
order Akorn lean online
order cough syrup online
lean in USA
Buy counterfeit online Docs and Counterfeits
ReplyDeleteBuy weed online Mister Cannabis Online
Excellent post. I was always checking this blog, and I’m impressed! Extremely useful info specially the last part, I care for such information a lot. I was exploring this particular info for a long time. Thanks to this blog my exploration has ended.
ReplyDeleteIf you want Digital Marketing Serives :-
Digital marketing Service in Delhi
SMM Services
PPC Services in Delhi
Website Design & Development Packages
SEO Services PackagesLocal SEO services
E-mail marketing services
YouTube plans
https://k2incenseonlineheadshop.com/
ReplyDeleteinfo@k2incenseonlineheadshop.com
k2incenseonlineheadshop Buy liquid incense cheap Buy liquid incense cheap For Sale At The Best Incense Online Shop
Hi there,
ReplyDeleteThank you so much for the post you do and also I like your post, Are you looking for Buy K2 Liquid Online,Buy K2 Spray Online in the whole USA? We are providing Buy K2 Spray Online,Buy Liquid K2 Online,k2 spray on paper,k2 spray for sale,liquid k2 On Paper,Buy k2 spray online,k2 spray for sale,Buy k2 spray,buy k2 paper online,buy k2 paper,K2 Paper For Sale,K2 eliquid CODE RED 5ml,Buy Liquid K2 Online,Liquid Spice Incense,buy cheap k2 spray,Liquid Herbal Incense,K2 spray for sale online,K2 liquid Spray On Paper,Buy Weed Online,buy marijuana online,marijuana for sale,weed for sale,Buy Shatter Online ,USABuy Shatter Online Cheap USA,Mail Order Marijuana,Order Marijuana Onlinewith the well price and our services are very fast.
Click here for Contact: +1 213 342 1053, Email: service@cbdwarehousestore.com
ReplyDeletehttps://buydocumentation.com/
Buy Driver’s License online, US driver license, drivers license renewal ca WhatsApp +1 (925) 526-5453
Here at Buy Documentation, you can buy fake documents at a fraction of a cost. We keep our prices low to meet the needs of all our customers. We provide Best Quality Novelty Real and Fake IDs and Passport, Marriage Certificates and Drivers license online
https://buydocumentation.com/canada-visa/
https://buydocumentation.com/buy-real-drivers-license/
https://buydocumentation.com/buy-real-id-cards/
https://buydocumentation.com/social-security-number-ssn/
Shop
ReplyDeleteCodeine phosphate 15 mg Tablets
PHOSPHATESTramadol 50mg
Silver Liquid MercurySSD Chemical Solution
Buy Blue Punisher 274mg MDMA
Buy Ethylone Crystal
Buy MDMA Online
PV8-Crystal
Buy Crystal Meth Online
Buy Anesket Online
Buy Nembutal Powder
Pink and Purple Skype MDMA
Buy Blue Toyotas online
Donkey Kong 453mg MDMA
Buy Morning Glory Seeds
Buy kratom Packs Online
Buy MDMA Pills Online
Shop
CANNABIS DISPENSARY GOALS
ReplyDeleteWe are the most legit cannabis dispensary with both wholesale and retail weed for sale. Marijuana extract and thc cartridges are also available. We deliver in almost all states in the US and Puerto Rico. We are available in Canada, UK, USA, South America, Europe and Australia
Buy Krt Carts Online
Buy Pluto Strain Online
Buy Sweet Tea Online
Buy White Runtz Sungrown Online
Buy Banana Kush Online
Buy Bubbleberry Strain Online
Buy Pink Panther Online
Buy White Runtz
Packwoods x gashouse Tear gas
https://cookieswood.com/shop/
My spouse and I absolutely love your blog and find most of your post's to
ReplyDeletebe precisely what I'm looking for. Does one offer guest writers to write content for you?
I wouldn't mind creating a post or elaborating on a few of the subjects you write related
to here. Again, awesome site!
Buy Blueberry Kush Online
Buy Wedding Crashers Jungleboys
Buy Jungle cake Jungleboys
Buy Banana Runtz online
Buy Sharklato Runtz
Buy Ether Runtz Online
Buy Whole lotta Runtz
Buy MoneyBagg Runtz
Buy White fire Jungleboys
Buy Afghan Hawaiian Strain Online
Buy Strawberry Shortcake Jungleboys
Buy Motor Breath Jungleboys
Buy Sunset Sherbert Jungleboys
Buy White Wookies Jungleboys
Buy Dr zodiak’s Moonrock
Buy Moonrocks Online
Buy Afghan Hawaiian Strain Online
Buy Girl Scout Cookies kush
Buy master bubba kush Online
Buy Buy OG Kush
Buy Fire OG Kush Online
Buy Moon Rock kush
Buy Pink Sandy Weed
Buy Pink Sandy Weed
Buy Blue widow online
Buy Levels Strain Online
Buy Yellow Zushi Weed
Buy OG Kush Online
Buy Afghan Hawaiian Strain Online
Buy Girl Scout Cookies kush
Buy master bubba kush Online
Buy Buy OG Kush
Buy Fire OG Kush Online
Buy Moon Rock kush
Buy Pink Sandy Weed
Buy Pink Sandy Weed
Buy Blue widow online
Buy Levels Strain Online
Buy Yellow Zushi Weed
Buy OG Kush Online
ReplyDeleteOur online store is one of the best in the supply of rare and high-grade (Mushrooms, Edibles. Psychedelics, and more)with absolute purity. All our products are tested to guarantee potency after production, during distribution and even storage. We ship globally in discreet and undetectable packaging using our network of trusted partners.
psilosybin mushroom 2022, trusted magic mushroom site 2022,
cheap liquid lsd, order cheap psychedelic mushroom,
cheap magic mushroom, super quality shrooms,
most potent psilocybin mushroom on the market,
best microdosing mushrooms 2022, Golden teacher mushroom for sale,
where to buy B+ magic mushroom, buy shrooms online ,
buy psilocybin mushroom overnight shipping, effective microdosing for ptsd,
buy mushroom truffles online cash on delivery, buy microdose capsules online 2021,
magic mushrooms for mental illness for sale,
buy mushies for anxiety/deppression and ptsd, cheap psilocybin mushroom, shrooms near me,
where to buy psilocybin mushroom near me, cheap psychedelic mushroom for sale,
buy caps/buttons cheap, best place to buy magic mushroom,
buy cheap fungi mushrooms, cheap strong fungus, best quality spores for sale,
buy mushroom grow kit online, buy fungi shrooms near me, cheapest magic mushrooms online,
where to buy penis envy online, where to buy mexicanna online, buy microdose capsules online,
best microdose capsule for sale,
fungi mushroom for sale, best liquid cultures online, buy spores near me, buy Nirvana mushroom near me,
buy pajaritos mushrooms near me, psychedelic mushroom near me, buy medicinal mushroom online,
buy 5-MeO-DMT, buy dmt vape pen online, buy lsd tabs online, buy dmt online, where to buy dmt,
lsd for sale, buy mushies near me, buy shrooms wholesale price, strong boomers for sale,
Buy trippy shrooms online, buy penis envy, buy albino A+, buy amazonian cubensis,
buy psilocybe cubensis, buy blue meanie, buy vietam cubensis, buy z strain shrooms,
buy boomers cubensis online, buy cubensis buy golden teacher, buy liquid lsd online
Our quality is the best you can find around and we sell in small/large quantities with guaranteed discreet delivery in good time Shipping
website...https://megapsilocybin.com/
call/text..+1(458) 201-6900
email..sale@megapsilocybin.com
First You got a great blog. I will be interested in more similar topics. I see you got really very useful topics, I will be always checking your blog thanks.
ReplyDeleteP.D.U.S.U. B.A 3rd Year Exam Result
CCSU BA 3rd Year Result
BA Final Year Result MGSU Name Wise
Orb 25 is a leading provider of Digital Integrated Business Services and Transformation Solutions for clients from around the world, representing all industry types.
ReplyDeleteExperience
Our company delivers proven solutions for optimizing processes, delivering exceptional customer experiences, and ensuring unmatched business agility.
Quick Support
Our technology solutions have world-class, award-winning security measures
and compliance with all Security Standards and Regulations.
We represent a global Center of Excellence within the Orb25 group for delivering customized and cost-effective Back-Office services, Digital, and web marketing services, Event management, Call center services, Video production services, etc.
orb25
ReplyDelete