Security News
38% of CISOs Fear They’re Not Moving Fast Enough on AI
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
github.com/gathering/gondulapi
This is the API engine that will be used for the Gondul backend in the future. At present, this is very much a work in progress and should NOT be used unless you talk to me directly about it first - unless you like breaking things.
The design goals are:
To achieve this, we aim that users of the Gondul API will work mainly with organizing their own data types and how they are interconnected, and not worry about how that is parsed to/from JSON or checked for type-safety.
The HTTP-bit is pretty small, but important. It's worth noting that users of the api-code will not have access to any information about the caller. This is a design decision - it's not your job, it's the job of the HTTP-server (which is represented by the Gondul API engine here). If your data types rely on data from the client, you're doing it wrong.
The database-bit can be split into a few categories as well. But mainly, it is an attempt to make it unnecessary to write a lot of boiler-plate to get sensible behavior. It is currently written with several known flaws, or trade-offs, so it's not suited for large deployments, but can be considered a POC or research.
In general, the DB engine uses introspection to figure out how to figure out how to retrieve and save an object. The Update mechanism will only update fields that are actually provided (if that is possible to detect!).
Don't do it if you don't talk to me first :D
Assuming you have...
To use gondulapi, know that everything in the objects
package can and
should be separate repos - this is what you want to provide/write yourself.
For now, what's in there is kept because it's a hassle to develop a library
in a separate repo from the code using it at the moment.
So what you want to do is make your own objects/ package and cmd/test to kick it off.
cmd/test is easy enough: It just imports objects for side effects and starts the receiver.
Your job is to make objects. An object is something that can be represented
by a URL. Objects are made by defining a data type and providing at least
ONE of the gondulapi.Getter / Putter / Poster / Deleter interfaces, then
letting the receiver module know about the object with
receiver.AddHandler
::
receiver.AddHandler("/test/", func() interface{} { return &Test{} })
This will register the Test object to the /test/ url. When the receiver gets a request for /test/, it will call the allocation function which allocates an empty Test struct. For write-methods, the receiver will json-parse the body of the request for you before the appropriate Put/Post/Delete method is called (if you implement it).
For GET, the inverse is true: The struct will remain empty, but you need to implement the code that fills in the blanks.
This means that your data types must implement MarshalJSON and UnmarshalJSON.
Since 99% of Gondul is simple database access where a URL matches a table
(or view, if you're fancy :D), gondulapi/db
implements some fancy as
fudge introspection magic. It might be a bit overkill...
But: The idea behind gondulapi/db
is to provide you with both the regular
database abstractions you're used to, and kick it up a notch by using
marshaling and introspection to generate the correct queries, for both
insert and get.
E.g.: If your object only has elements that sql/driver can deal with (e.g.: uses sql.Scan and sql.Value interface), you can use db.Select() or db.Update() without writing any SQL. It's not 100% pretty, but OK. Here's an exmaple for getting a documentation stub::
return db.Get(ds, "docs", "family", "=", family, "shortname", "=", shortname)
Here "ds" is a reference to the Docstub struct that will be populated, "docs" is the table to look for, and the rest are quadruplets of key/operator/values used in the WHERE statement.
The following is a complete implementation of POST for a documentation stub, excluding the init() AddHandler call.
::
type Docstub struct { Family *string Shortname *string Name *string Sequence *int Content *string *auth.ReadPublic }
func (ds Docstub) Post() (gondulapi.Report, error) { if ds.Family == nil || *ds.Family == "" || ds.Shortname == nil || *ds.Shortname == "" { return gondulapi.Report{Failed: 1}, gondulapi.Errorf(400, "Need to provide Family and Shortname for doc stubs") } return db.Upsert(ds, "docs", "family", "=", ds.Family, "shortname", "=", ds.Shortname) }
The write functions all return a report combined with an error. This is to provide feedback to the user on how many items were modified/added.
Where this gets more interesting is for more complex objects or less trivial data types. E.g.: If your data type deals with time, time.Time can be used without worrying about converting it back and forth.
You can also implement more complex data types yourself. Some are provided
in gondulapi/types
, where the raw value didn't implement sql.Scan or
similar. Examples are IP addresses, generic JSON, Postgres' box datatype,
and so forth.
But even if this is provided, you can still just use your own SQL as well. But hopefully you wont feel like doing that.
Some things that are worth considering:
FAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.
Security News
Company News
Socket is joining TC54 to help develop standards for software supply chain security, contributing to the evolution of SBOMs, CycloneDX, and Package URL specifications.